<?php
namespace Home\Server;
use Home\Server\getRedisService;
use Home\Server\QueuePushService;

/**
 * Class ParcelService
 *
 * Author: 黄盖
 * Date: 2017-59-17 17:59
 * Info: 包裹系统数据逻辑处理
 */
class ParcelService
{
    public $NowTime;                      //当前时间
    protected $Month_TableName_Now;       //当前月份的表名
    protected $Month_TableName_Last;      //上个月份的表名

    protected $LastTableName;             //连表操作的上一个表名

    public $redis;                        //redis

    function __construct()
    {
        $this ->NowTime                 = time();
        $this ->Month_TableName_Now     = 'tp_parcel_info_' . date('Ym', $this ->NowTime);
        $this ->Month_TableName_Last    = 'tp_parcel_info_' . date('Ym', strtotime('-1 month', $this ->NowTime));

        $this ->LastTableName();

        //自动创建表
        $Allow = $this ->Table_Exists();

        if( ! $Allow )
        {
            return False;
        }

        //加载redis
        $this ->redis = ( new getRedisService() ) ->redis;
    }

    /**
     * Function PutStorage
     * @param array $Data
     * @param string $Professional
     * Author: 黄盖
     * Date: 2017-24-18 9:24
     * Info: 入库
     */
    public function PutStorage( $Data = Array() , $Professional = '' )
    {
        //整合数据
        $StorageData = $this ->Integrate( $Data );

        //缓存站点信息
        $this ->UserInfo_Redis( $StorageData[0]['f_station_id'] );

        //实时推送数据 (如果是新插入数据，以及修改手机号码不同数据)
        $Real_Delivery = Array();

        //获取能用的提货码
        $TakeCodeData = $this ->Allow_TakeCode( $StorageData[0]['f_station_id'], count( $StorageData ) );

        //获取运单号是否重复
        //$MailNOData_Repeat = $this ->MailNO_Repeat( $StorageData[0]['f_station_id'], $this ->getMailNO( $StorageData ) );
        $MailNOData_Repeat = Array();

        $insert_StorageData = Array();      //待插入数据
        $update_StorageData = Array();      //待更新数据

        //去重， 没有重复的插入、有重复的更新
        foreach ( $StorageData as $SKey => $SVal )
        {
            $isExists = False;

            foreach ( $MailNOData_Repeat as $RKey => $RVal )
            {
                if( $SVal['f_mail_no'] == $RVal['f_mail_no'] )
                {
                    $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ] = $SVal;

                    //替换提货码
                    $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ]['f_take_code'] = $TakeCodeData[ $SKey ];

                    //入库时间
                    $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ]['f_arrive_time']      = date('YmdHis', $this ->NowTime);
                    $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ]['f_arrive_timestamp'] = $this ->NowTime;

                    //最后更新时间
                    $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ]['f_last_time']      = date('YmdHis', $this ->NowTime);
                    $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ]['f_last_timestamp'] = $this ->NowTime;


                    $isExists = True;



                    /**
                     * 如果是修改包裹详情
                     *      原手机号码 与 将要修改的号码不一致
                     *          则推送信息
                     */
//                    if( $RVal['f_recipient_mobile'] != $SVal['f_recipient_mobile'] )
//                    {
//                        $Real_Delivery[] = array_merge( Array( 'f_parcel_id' => $RVal['f_parcel_id'], 'table_name' => $RVal['table_name'] ), $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ] );
//                    }

                    //组合完善更新 微信、短信通知队列表 的数据
                    $UpdateParcelNotice_Data[] = array_merge( Array( 'f_parcel_id' => $RVal['f_parcel_id'] ), $update_StorageData[ $RVal['table_name'] ][ $RVal['f_parcel_id'] ] );
                }
            }

            if( ! $isExists )
            {
                $insert_StorageData[ $SKey ] = $SVal;

                //创建提货码
                $insert_StorageData[ $SKey ]['f_take_code'] = $TakeCodeData[ $SKey ];

                //入库时间
                $insert_StorageData[ $SKey ]['f_arrive_time']       = date('YmdHis', $this ->NowTime);
                $insert_StorageData[ $SKey ]['f_arrive_timestamp']  = $this ->NowTime;

                //最后更新时间
                $insert_StorageData[ $SKey ]['f_last_time']       = date('YmdHis', $this ->NowTime);
                $insert_StorageData[ $SKey ]['f_last_timestamp']  = $this ->NowTime;
            }
        }

        //重置插入索引
        sort( $insert_StorageData );

        //插入新数据
        $InsertFirstID = $this ->insert_StorageData( $insert_StorageData );

        //更新旧数据
        //$return['updateResult'] = $this ->update_StorageData( $update_StorageData );
        $return['updateResult'] = Array();

        /**
         * 包裹入库
         *      运单号 不存在     -> 插入包裹表        -> 插入微信、短信队列表
         *                  是否是合作快递公司 && 站点是否注册快递       -> 插入快递推送队列表
         *
         *      运单号 存在      -> 更新包裹表        -> 更新微信、短信队列表 (状态改为待发送)
         *
         */

        //队列服务层
        $QueuePush = new QueuePushService();

        $InsertAddNum = 0;

        //查询收件人是否需要发送通知
        $Receive = new \Home\Model\ReceiveLabelModel();

        //组合完善新插入的数据
        foreach ( $insert_StorageData as $IKey => $IVal )
        {

            $insert_StorageData[ $IKey ]['f_weixin_notice'] = 0;
            $insert_StorageData[ $IKey ]['f_weixin_num'] = 0;
            $insert_StorageData[ $IKey ]['f_sms_notice'] = 0;
            $insert_StorageData[ $IKey ]['f_weixin_notice'] = 0;

            //验证用户是否需要发送信息及类型  2017-04-26 quyang
            $send_type = $Receive->querySendLabelStatus( $IVal['f_station_id'] , $IVal['f_recipient_mobile'] );

            if ( is_array( $send_type ) && count( $send_type ) > 0 )
            {

                $Label = new \Home\Model\LabelModel();
                $send_status_data = $Label->queryLabelDetails( $send_type['f_receive_label_id'] );

                //发送类型为2为只发送短信
                if ( $send_status_data['f_send_type'] == 2 )
                {
                    $insert_StorageData[ $IKey ]['f_weixin_notice'] = 2;
                    $insert_StorageData[ $IKey ]['f_weixin_num'] = 1;
                    $insert_StorageData[ $IKey ]['f_sms_notice'] = 0;
                    $insert_StorageData[ $IKey ]['f_sms_num'] = 0;
                }
                //发送类型为3时不需要发送任何信息
                elseif ( $send_status_data['f_send_type'] == 3 )
                {
                    $insert_StorageData[ $IKey ]['f_weixin_notice'] = 2;
                    $insert_StorageData[ $IKey ]['f_weixin_num'] = 1;
                    $insert_StorageData[ $IKey ]['f_sms_notice'] = 2;
                    $insert_StorageData[ $IKey ]['f_sms_num'] = 1;
                }

            }

            $insert_StorageData[ $IKey ]['f_parcel_id'] = $InsertFirstID + $InsertAddNum;
            $insert_StorageData[ $IKey ]['table_name'] = $this ->Month_TableName_Now;

            //普通版为0  专业版入库为1  极速版入库为2
            if ( $Professional == '' )
            {
                $insert_StorageData[ $IKey ]['f_speed_status'] = '0';
            }
            else
            {
                $insert_StorageData[ $IKey ]['f_speed_status'] = $Professional;
            }

            $InsertAddNum ++;
        }

        //插入微信、短信通知队列表
        $QueuePush ->IntoParcelNotice( $insert_StorageData );

        //更新微信、短信通知队列表
        //$QueuePush ->UpdateParcelNotice( $UpdateParcelNotice_Data );

        //插入快递对接通知队列表
        $QueuePush ->IntoParcelExpress( $insert_StorageData );


        /**
         * 包裹入库, 记录收件人信息
         */
        $this ->saveRecipients( $StorageData, $StorageData[0]['f_station_id'] );

        //实时推送
//        $this ->Parcel_RealDelivery( $insert_StorageData, $update_StorageData );

        $return['insertResult'] = $insert_StorageData;

        return $return;
    }

    /**
     * Function saveRecipients
     * @param $StorageData
     *
     * Author: 黄盖
     * Date: 2017-2-13 15:48
     * Info: 包裹入库同时, 将收件人信息保存
     */
    public function saveRecipients( $StorageData, $stationID = 0 )
    {
        $MobileData = Array();

        //获取入库的手机号码与姓名
        foreach( $StorageData as $SVal )
        {
            //（取消）  用户名为空, 不存  //$SVal[ 'f_recipient_name' ] != '' &&
            if( ! array_key_exists( $SVal['f_recipient_mobile'], $MobileData ) )
            {
                $MobileData[ $SVal['f_recipient_mobile'] ]  = strval( $SVal[ 'f_recipient_name' ] );
            }
        }

        //给另张表用
        $MobileData_2 = $MobileData;

        if( count( $MobileData ) > 0 )
        {
            $MobileSql = '';

            foreach ( $MobileData as $MKey => $MVal )
            {
                $MobileSql .= "'" .$MKey . "',";
            }

            $MobileSql = substr( $MobileSql, 0, -1 );

            /**
             * 包裹入库将联系人保存
             * ************************************** tp_recipient_info **************************************
             */

            //获取数据是否有重复
            $recipientExists = ( new \Think\Model() )
                                    ->table( 'tp_recipient_info' )
                                    ->where( "`f_mobile` IN ( {$MobileSql} )" )
//                                    ->buildSql()
                                    ->select()
                            ;

            //去除重复
            foreach ( $recipientExists as $RVal )
            {
                if( array_key_exists( $RVal['f_mobile'], $MobileData ) )
                {
                    unset( $MobileData[ $RVal['f_mobile'] ] );
                }
            }


            //组建插入数据
            foreach( $MobileData as $DKey => $DVal )
            {
                $recipientData[] = Array( 'f_mobile' => $DKey, 'f_name' => $DVal );
            }

            //存入数据库
            ( new \Think\Model() ) ->table( 'tp_recipient_info' ) ->addAll( $recipientData );



            /**
             * 包裹入库将联系人保存另一张表
             * ************************************** tp_mobile_info **************************************
             */


            //获取数据是否有重复
            $recipientExists_2 = ( new \Think\Model() )
                ->table( 'tp_mobile_info' )
                ->where( "`f_user_id` = '{$stationID}' AND `f_recipient_mobile` IN ( {$MobileSql} )" )
                ->select()
            ;

            //去除重复
            foreach ( $recipientExists_2 as $RVal_2 )
            {
                if( array_key_exists( $RVal_2['f_recipient_mobile'], $MobileData_2 ) )
                {
                    unset( $MobileData_2[ $RVal_2['f_recipient_mobile'] ] );

                    //查询收件人手机号状态
                    $MobileInfo = new \Home\Model\MobileInfoModel();
                    $delete_mobile = $MobileInfo->queryRecipientMobile( $stationID , 0 , $RVal_2['f_id'] , 1 );

                    if ( is_array( $delete_mobile ) && count( $delete_mobile ) > 0 )
                    {
                        //更新收件人状态   ----  重新入库已删除收件人 恢复正常状态  2017-05-02  quyang
                        $MobileInfo->updateMobile( $RVal_2['f_id'] , $stationID , '' , '' , '' , '' , '0' );
                    }

                }
            }

            //收件人信息
            $Recipient_Data = Array();

            //组建插入数据
            foreach( $MobileData_2 as $DKey_2 => $DVal_2 )
            {
                $recipientData_2[] = Array( 'f_recipient_mobile' => $DKey_2, 'f_recipient_name' => $DVal_2, 'f_user_id' => $stationID, 'f_create_time' => $this ->NowTime );

                //组建收件人信息, 插入redis, 供APP实时查询
                $Recipient_Data[] = Array(
                                        'fUserID'           => $stationID,
                                        'fRecipientMobile'  => $DKey_2,
                                        'fRecipientName'    => $DVal_2 ,
                                        'fRecipientPhone'   => '',
                                        'fAddress'          => '',
                                        'fStatus'           => '0',
                                        'label'             => '[]'
                );
            }

            //存入数据库
            $mobileIndex = ( new \Think\Model() ) ->table( 'tp_mobile_info' ) ->addAll( $recipientData_2 );

            //将用户信息存入redis
            ( new \Home\Server\RedisData() ) ->First_RecipientData( $Recipient_Data, $mobileIndex );
        }
    }


    /**
     * Function getStorageList
     * @param $station_id
     * @param string $String
     *
     * Author: 黄盖
     * Date: 2017-36-19 11:36
     * Info: 通过手机号、提货码 查询 用户在该站点 所有待操作数据 列表
     */
    public function getStorageList( $station_id, $String = '' )
    {
        //专业版跟普通版查询条件不同
        if( ( new \Home\Server\UserService() ) ->verify_professional( $station_id ) )
        {
            //专业版 只能输入 包裹编号 和 手机号码
            $field = $this ->getprofessional_StorageField( $String );
        }
        else
        {
            //普通版 只能输入 运单号  手机号码  提货码
            $field = $this ->getStorageField( $String );
        }

        //如果查询手机号码, 则不用IN
        if( $field == 'f_recipient_mobile' )
        {
            $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND `f_recipient_mobile` = '{$String}' AND `f_parcel_status` IN ( 0, 2, 5 ) ";
        }
        //如果查询运单号, 则不用IN.  取一条
        else if( $field == 'f_mail_no' )
        {
            $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND `f_mail_no` = '{$String}' AND `f_parcel_status` IN ( 0, 2, 5 ) ";
        }
        //查询包裹编号
        else if( $field == 'f_num' )
        {
//            $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND `f_num` = '{$String}' AND `f_parcel_status` IN ( 0, 2, 5 ) ";

            $whereSql_NowTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` IN 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_num` = '{$String}'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_num` = '{$String}'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                        )
                                                ) AS `code_mobile`
                                            GROUP BY `f_recipient_mobile`
                                        )
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
            $whereSql_LastTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` IN 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_num` = '{$String}'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_num` = '{$String}'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                        )
                                                ) AS `code_mobile`
                                            GROUP BY `f_recipient_mobile`
                                        ) 
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
        }
        //提货码
        else
        {
            $whereSql_NowTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` = 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_take_code` = '". intval( $String ) ."'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                        LIMIT 1
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_take_code` = '". intval( $String ) ."'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                            LIMIT 1
                                                        )
                                                ) AS `code_mobile`
                                            LIMIT 1
                                        )
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
            $whereSql_LastTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` = 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_take_code` = '". intval( $String ) ."'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                        LIMIT 1
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_take_code` = '". intval( $String ) ."'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                            LIMIT 1
                                                        )
                                                ) AS `code_mobile`
                                            LIMIT 1
                                        ) 
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
        }


        //查询SQL
        $ListData = ( new \Think\Model() )
                    ->table( $this ->Month_TableName_Now )
                    ->field("
                                f_parcel_id as packageId,
                                f_recipient_mobile as mobile,
                                f_num as num,
                                f_mail_no as mailNo,
                                f_company_name as companyName,
                                f_frame_code as frameCode,
                                f_arrive_time as arriveTime,
                                `f_arrive_timestamp` AS arriveTimestamp,
                                FROM_UNIXTIME( `f_arrive_timestamp`, '%Y-%m-%d %H:%i:%S') AS arriveTimeDate,
                                f_recipient_name as recName,
                                `f_station_id`,
                                `f_take_code`,
                                `f_parcel_status`,
	                            '{$this ->Month_TableName_Now}' AS `tableName`
                            ")
                    ->where( "
                                {$whereSql_NowTable}
                            ")
                    ->UNION( "
                            SELECT 
                                f_parcel_id as packageId,
                                f_recipient_mobile as mobile,
                                f_num as num,
                                f_mail_no as mailNo,
                                f_company_name as companyName,
                                f_frame_code as frameCode,
                                f_arrive_time as arriveTime,
                                `f_arrive_timestamp` AS arriveTimestamp,
                                FROM_UNIXTIME( `f_arrive_timestamp`, '%Y-%m-%d %H:%i:%S') AS arriveTimeDate,
                                f_recipient_name as recName ,
                                `f_station_id`,
                                `f_take_code`,
                                `f_parcel_status`,
	                            '{$this ->LastTableName}' AS `tableName`
                                FROM 
                                  `{$this ->LastTableName}`
                                WHERE
                                    {$whereSql_LastTable}
                                ORDER BY arriveTimestamp DESC  
                            ")
                        ->select()
//                    ->buildSql()
            ;

        return $ListData;
    }

    /**
     * Function getStorageList
     * @param $station_id
     * @param string $String
     * Author: xushu
     * Date: 2017-07-11
     * Info: 通过手机号、提货码 查询 用户在该站点 所有待操作数据 列表(查询运单号联系人下的所有包裹)
     */
    public function getStorageListBeta( $station_id, $String = '' )
    {
        //专业版跟普通版查询条件不同
        if( ( new \Home\Server\UserService() ) ->verify_professional( $station_id ) )
        {
            //专业版 只能输入 包裹编号 和 手机号码
            $field = $this ->getprofessional_StorageField( $String );
        }
        else
        {
            //普通版 只能输入 运单号  手机号码  提货码
            $field = $this ->getStorageField( $String );
        }

        //如果查询手机号码, 则不用IN
        if( $field == 'f_recipient_mobile' )
        {
            $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND `f_recipient_mobile` = '{$String}' AND `f_parcel_status` IN ( 0, 2, 5 ) ";
        }
        //查询运单号，并查询对应的联系人手机号码，查找此联系人下的所有包裹
        else if( $field == 'f_mail_no' )
        {
            $mobli_no = $this -> getStorageListByMailNo( $station_id, $String ,'IN (0,2,5)');
            if ($mobli_no[0]['mobile'])
            {
                $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND ( `f_mail_no` = '{$String}' OR `f_recipient_mobile` = '".$mobli_no[0]['mobile']."' ) AND `f_parcel_status` IN ( 0, 2, 5 ) ";
            }
            else
            {
                $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND `f_mail_no` = '{$String}' AND `f_parcel_status` IN ( 0, 2, 5 ) ";
            }
        }
        //查询包裹编号
        else if( $field == 'f_num' )
        {
//            $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$station_id}' AND `f_num` = '{$String}' AND `f_parcel_status` IN ( 0, 2, 5 ) ";

            $whereSql_NowTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` IN 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_num` = '{$String}'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_num` = '{$String}'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                        )
                                                ) AS `code_mobile`
                                            GROUP BY `f_recipient_mobile`
                                        )
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
            $whereSql_LastTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` IN 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_num` = '{$String}'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_num` = '{$String}'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                        )
                                                ) AS `code_mobile`
                                            GROUP BY `f_recipient_mobile`
                                        ) 
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
        }
        //提货码
        else
        {
            $whereSql_NowTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` = 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_take_code` = '". intval( $String ) ."'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                        LIMIT 1
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_take_code` = '". intval( $String ) ."'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                            LIMIT 1
                                                        )
                                                ) AS `code_mobile`
                                            LIMIT 1
                                        )
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
            $whereSql_LastTable = "
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` = 
                                        (
                                            SELECT
                                                *
                                            FROM
                                                (
                                                    (
                                                        SELECT
                                                            `f_recipient_mobile`
                                                        FROM
                                                            `{$this ->Month_TableName_Now}`
                                                        WHERE
                                                            `f_station_id` = '{$station_id}'
                                                        AND `f_take_code` = '". intval( $String ) ."'
                                                        AND `f_parcel_status` IN (0, 2, 5)
                                                        LIMIT 1
                                                    )
                                                    UNION
                                                        (
                                                            SELECT
                                                                `f_recipient_mobile`
                                                            FROM
                                                                `{$this ->LastTableName}`
                                                            WHERE
                                                                `f_station_id` = '{$station_id}'
                                                            AND `f_take_code` = '". intval( $String ) ."'
                                                            AND `f_parcel_status` IN (0, 2, 5)
                                                            LIMIT 1
                                                        )
                                                ) AS `code_mobile`
                                            LIMIT 1
                                        ) 
                                    AND `f_parcel_status` IN ( 0, 2, 5 ) 
                                    ";
        }


        //查询SQL
        $ListData = ( new \Think\Model() )
            ->table( $this ->Month_TableName_Now )
            ->field("
                                f_parcel_id as packageId,
                                f_recipient_mobile as mobile,
                                f_num as num,
                                f_mail_no as mailNo,
                                f_company_name as companyName,
                                f_frame_code as frameCode,
                                f_arrive_time as arriveTime,
                                `f_arrive_timestamp` AS arriveTimestamp,
                                FROM_UNIXTIME( `f_arrive_timestamp`, '%Y-%m-%d %H:%i:%S') AS arriveTimeDate,
                                f_recipient_name as recName,
                                `f_station_id`,
                                `f_take_code`,
                                `f_parcel_status`,
	                            '{$this ->Month_TableName_Now}' AS `tableName`
                            ")
            ->where( "
                                {$whereSql_NowTable}
                            ")
            ->UNION( "
                            SELECT 
                                f_parcel_id as packageId,
                                f_recipient_mobile as mobile,
                                f_num as num,
                                f_mail_no as mailNo,
                                f_company_name as companyName,
                                f_frame_code as frameCode,
                                f_arrive_time as arriveTime,
                                `f_arrive_timestamp` AS arriveTimestamp,
                                FROM_UNIXTIME( `f_arrive_timestamp`, '%Y-%m-%d %H:%i:%S') AS arriveTimeDate,
                                f_recipient_name as recName ,
                                `f_station_id`,
                                `f_take_code`,
                                `f_parcel_status`,
	                            '{$this ->LastTableName}' AS `tableName`
                                FROM 
                                  `{$this ->LastTableName}`
                                WHERE
                                    {$whereSql_LastTable}
                                ORDER BY arriveTimestamp DESC  
                            ")
            ->select()
//                    ->buildSql()
        ;

        return $ListData;
    }



    /**
     * 根据站点id与运单号查询两个月的包裹
     * @param $stationId
     * @param $mailNo
     * @return mixed
     * @Author xushu
     */
    public function  getStorageListByMailNo($stationId ,$mailNo, $str='NOT IN(4,6)')
    {
        $whereSql_NowTable = $whereSql_LastTable = "`f_station_id` = '{$stationId}' AND `f_mail_no` = '{$mailNo}' AND `f_parcel_status` {$str} ";

        //查询SQL
        $ListData = ( new \Think\Model() )
            ->table( $this ->Month_TableName_Now )
            ->field("
                                f_parcel_id as packageId,
                                f_recipient_mobile as mobile,
                                f_num as num,
                                f_mail_no as mailNo,
                                f_company_name as companyName,
                                f_frame_code as frameCode,
                                f_arrive_time as arriveTime,
                                `f_arrive_timestamp` AS arriveTimestamp,
                                FROM_UNIXTIME( `f_arrive_timestamp`, '%Y-%m-%d %H:%i:%S') AS arriveTimeDate,
                                f_recipient_name as recName,
                                `f_station_id`,
                                `f_take_code`,
                                `f_parcel_status`,
	                            '{$this ->Month_TableName_Now}' AS `tableName`
                            ")
            ->where( "
                                {$whereSql_NowTable}
                            ")
            ->UNION( "
                            SELECT 
                                f_parcel_id as packageId,
                                f_recipient_mobile as mobile,
                                f_num as num,
                                f_mail_no as mailNo,
                                f_company_name as companyName,
                                f_frame_code as frameCode,
                                f_arrive_time as arriveTime,
                                `f_arrive_timestamp` AS arriveTimestamp,
                                FROM_UNIXTIME( `f_arrive_timestamp`, '%Y-%m-%d %H:%i:%S') AS arriveTimeDate,
                                f_recipient_name as recName ,
                                `f_station_id`,
                                `f_take_code`,
                                `f_parcel_status`,
	                            '{$this ->LastTableName}' AS `tableName`
                                FROM 
                                  `{$this ->LastTableName}`
                                WHERE
                                    {$whereSql_LastTable}
                                ORDER BY arriveTimestamp DESC  
                            ")
            ->select();

        return $ListData;
    }

    /**
     * Function pickUp
     * @param $station_id               站点ID
     * @param $mobile
     * @param $take_code
     * @param int $parcelIDSQL          包裹ID
     * @param bool $useSuperPwd         是否使用超级密码 /  如果用户是专业版, 也使用这个参数, 不需要提货码直接提货
     *
     *
     * @param int $out_way              出库平台  0 未知  1 IOS  2 Andoird  3 PC  5 微信
     * @param int $out_source           出库方式  1 提货码  6 超级密码  7 专业版  8 微信扫码
     *
     * @return bool
     *
     * Author: 黄盖
     * Date: 2017-3-21 17:42
     * Info: 创建一个方法
     */
    public function pickUp( $station_id, $mobile, $take_code, $parcelIDSQL = 1, $useSuperPwd = False, $out_way = 0, $out_source = 1 )
    {
        /**
         * 先查询出符合提货的包裹的 ID出来
         *  然后判别提货码是否 符合其中之一
         *  不符合不允许提货
         */
        $NowData = ( new \Think\Model() ) ->table( $this ->Month_TableName_Now ) ->field('`f_parcel_id`, `f_take_code`, `f_company_name`, `f_mail_no`, `f_station_id`') ->where("`f_station_id` = '{$station_id}' AND `f_recipient_mobile` = '{$mobile}' AND `f_parcel_status` IN (0, 2, 5)") ->select();
        $LastData = ( new \Think\Model() ) ->table( $this ->LastTableName ) ->field('`f_parcel_id`, `f_take_code`, `f_company_name`, `f_mail_no`, `f_station_id`') ->where("`f_station_id` = '{$station_id}' AND `f_recipient_mobile` = '{$mobile}' AND `f_parcel_status` IN (0, 2, 5)") ->select();

        //合并数据
        $AllData = array_merge( $NowData, $LastData );

        //需要提货的包裹ID
        $parcelID_Data = explode( ",", $parcelIDSQL );

        //$Updata_parcelID = '';
        $expressName = '';
        $fNumber = '';
        $Correct_TakeCode = False;

        foreach( $AllData as $AKey => $AVal )
        {
            //$Updata_parcelID .= $AVal['f_parcel_id'] . ",";

            //如果查询结果中包含了 一个正确的提货码, 则允许提货
            if( $useSuperPwd || $AVal['f_take_code'] == $take_code )
            {
                $Correct_TakeCode = True;
            }

            //多个可提货包裹, 只提其中几个, 只推送这几个
            if( in_array( $AVal['f_parcel_id'], $parcelID_Data ) )
            {
                //提货给微信推送消息
                $expressName .= $AVal['f_company_name'] . ",";
                $fNumber     .= $AVal['f_mail_no'] . ",";
            }
        }

        //$Updata_parcelID = substr( $Updata_parcelID, 0, -1 );
        $expressName     = substr( $expressName, 0, -1 );
        $fNumber         = substr( $fNumber, 0, -1 );

        if( $Correct_TakeCode )
        {
            //待更新数据
            $Updata = Array(
                'f_parcel_status'   => 1,
                'f_out_time'        => date('YmdHis', $this ->NowTime),
                'f_out_timestamp'   => $this ->NowTime,
                'f_last_time'       => date('YmdHis', $this ->NowTime),
                'f_last_timestamp'  => $this ->NowTime,
                'f_out_way'         => $out_way,                //出库平台  0 未知  1 IOS  2 Andoird  3 PC  5 微信
                'f_out_source'      => $out_source              //出库方式  1 提货码  6 超级密码  7 专业版  8 微信扫码
            );

            //更新最近两个月表
            $NowTableResult  = ( new \Think\Model() ) ->table( $this ->Month_TableName_Now ) ->where("`f_parcel_id` IN ( {$parcelIDSQL} )") ->save( $Updata );
            $LastTableResult = ( new \Think\Model() ) ->table( $this ->LastTableName ) ->where("`f_parcel_id` IN ( {$parcelIDSQL} )") ->save( $Updata );

            //推送微信消息
            $this ->pickUp_SendWX( $AllData[0]['f_station_id'], $mobile, $expressName, $fNumber );

            return $NowTableResult || $LastTableResult ? True : False;
        }
        else
        {
            return False;
        }
    }

    /**
     * Function pickUp_TableName
     * @param $station_id
     * @param $mobile
     * @param $take_code
     * @param int $parcelIDSQL
     * @param $tableName
     *
     * Author: 黄盖
     * Date: 2017-2-9 13:08
     * Info: 新的提货操作
     */
    public function pickUp_TableName( $station_id, $mobile, $take_code, $parcelIDSQL = 1, $tableName )
    {
        if( empty( $tableName ) )
        {
            return False;
        }


        $parcelData = ( new \Think\Model() )
                        ->table( $tableName )
                        ->field('`f_parcel_id`, `f_take_code`, `f_company_name`, `f_mail_no`, `f_station_id`')
                        ->where("
                                    `f_station_id` = '{$station_id}' AND 
                                    `f_recipient_mobile` = '{$mobile}' AND 
                                    `f_parcel_id` IN ( {$parcelIDSQL} ) AND 
                                    `f_parcel_status` IN (0, 2, 5)
                                ")
                        ->select();

        $Updata_parcelID = '';
        $expressName = '';
        $fNumber = '';
        $Correct_TakeCode = False;


        //需要提货的包裹ID
        $parcelID_Data = explode( ",", $parcelIDSQL );


        foreach( $parcelData as $AKey => $AVal )
        {
            $Updata_parcelID .= $AVal['f_parcel_id'] . ",";

            //如果查询结果中包含了 一个正确的提货码, 则允许提货
            if( $AVal['f_take_code'] == intval( $take_code ) )
            {
                $Correct_TakeCode = True;
            }

            //多个可提货包裹, 只提其中几个, 只推送这几个
            if( in_array( $AVal['f_parcel_id'], $parcelID_Data ) )
            {
                //提货给微信推送消息
                $expressName .= $AVal['f_company_name'] . ",";
                $fNumber     .= $AVal['f_mail_no'] . ",";
            }
        }

        $Updata_parcelID = substr( $Updata_parcelID, 0, -1 );
        $expressName     = substr( $expressName, 0, -1 );
        $fNumber         = substr( $fNumber, 0, -1 );

        if( $Correct_TakeCode )
        {
            //待更新数据
            $Updata = Array(
                'f_parcel_status'   => 1,
                'f_out_way'         => count( $parcelData ) > 0 ? 1 : 0,
                'f_out_time'        => date('YmdHis', $this ->NowTime),
                'f_out_timestamp'   => $this ->NowTime,
                'f_last_time'       => date('YmdHis', $this ->NowTime),
                'f_last_timestamp'  => $this ->NowTime
            );

            //推送微信消息
            $this ->pickUp_SendWX( $parcelData[0]['f_station_id'], $mobile, $expressName, $fNumber );

            //更新最近两个月表
            $TableResult  = ( new \Think\Model() ) ->table( $tableName ) ->where("`f_parcel_id` IN ( {$Updata_parcelID} )") ->save( $Updata );

            return $TableResult ? True : False;
        }
        else
        {
            return False;
        }

    }

    /**
     * Function pickUp_SendWX
     * @param $Mobile
     * @param $expressName
     * @param $fNumber
     * @param $stationAddr
     * @param $stationPhone
     *
     * Author: 黄盖
     * Date: 2017-2-21 17:29
     * Info: 收货WX提醒
     */
    public function pickUp_SendWX( $stationID, $Mobile, $expressName, $fNumber )
    {
        //用户(站点) 信息
        $UserInfo = ( new \Home\Server\QueuePushService() ) ->getUserInfo( $stationID );

        $PutData = Array(
                        'mobile'        => $Mobile,
                        'expressName'   => $expressName,
                        'fNumber'       => $fNumber,
                        'stationAddr'   => $UserInfo['f_address'],
                        'stationPhone'  => $UserInfo['f_user_phone']
                    );

        return $this ->useCURL_Post( 'http://wx.baimixu.cn/bg_ReceiveNotice.php', $PutData, 2 );
    }

    /**
     * Function use_CURL
     * @param $url
     * @param array $post_param
     * @param int $TimeOUT
     * @return mixed
     *
     * Author: 黄盖
     * Date: 2017-2-23 18:02
     * Info: CURL提交
     */
    public function useCURL_Post( $url, $post_param = Array(), $TimeOUT = 45, $DataType = '' )
    {
        $curl = curl_init();

        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_ENCODING, "");
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_POST, TRUE);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_param);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $TimeOUT);
        curl_setopt($curl, CURLOPT_TIMEOUT, $TimeOUT);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        if( $DataType == 'json' )
        {
            curl_setopt($curl, CURLOPT_HTTPHEADER, Array( 'Content-Type: application/json', 'Content-Length: ' . strlen( $post_param ) ) );
        }
        else
        {
            curl_setopt($curl, CURLOPT_HEADER, 0);
        }


        $data['content'] = curl_exec($curl);
        $data['error'] = curl_error($curl);
        $data['info'] = curl_getinfo($curl);

        curl_close($curl);

        return $data;
    }

    /**
     * Function getConditionStorage
     * @param $station_id               站点ID
     * @param string $mobile            收件人手机号码
     * @param $date                     查询月份 (废弃)
     * @param int $parcel_status        包裹状态
     * @param int $page                 当前第几页
     * @param int $size                 每页多少条
     *
     * @param int $expcomID             快递公司ID
     * @param string $mailNO            运单号
     * @param string $recipient_name    收件人
     * @param int $startDate            查询起始日期
     * @param int $endDate              查询结束日期
     * @param int $takeCode             提货码
     * @return mixed
     *
     * @return mixed
     *
     * Author: 黄盖
     * Date: 2017-1-19 17:17
     * Info: 多状态查询
     */
    public function getConditionStorage( $station_id, $mobile = '', $date = '', $parcel_status = 0, $page = 0, $size = 10
                                        , $expcomID = 0, $mailNO = '', $recipient_name = '', $startDate = 0, $endDate = 0, $takeCode = 0, $num = 0
                                )
    {

        //通用条件
        $ConditionSQL = $this ->getConditionSQL( $station_id, $mobile, $date, $parcel_status
                                                , $expcomID, $mailNO, $recipient_name, $takeCode, $num
                                        );

        //API版 date数据有用。 未传  $startDate $endDate。 数据转换
        if( $startDate == 0 || $endDate == 0 )
        {
            //开始日期
            $startDate = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-01';

            //结束日期
            $endDate = date('Y-m-d', strtotime( '+1 month', strtotime( $startDate . ' 00:00:00' ) ) - 1 );
        }


//        echo ( new \Home\Server\ParcelNoticeResultServer() ) ->getConditionTable_Result( $startDate, $endDate, '`f_parcel_id`,``f_weixin_notice`, `f_sms_notice`', '1=1' ) ->buildSql();
//        exit;

        $Data = $this ->getConditionTable_Result( $startDate, $endDate, '
                                                                            f_app_notice_status AS fAppNoticeStatus,
                                                                            f_company_id AS fCompanyId,
                                                                            f_company_name AS fCompanyName,
                                                                            f_input_source AS fInputSource,
                                                                            f_input_way AS fInputWay,
                                                                            f_is_detention AS fIsDetention,
                                                                            
                                                                            f_arrive_time AS fArriveTime,
                                                                            f_arrive_timestamp AS fArriveTimestamp,
                                                                            FROM_UNIXTIME( `f_arrive_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fArriveTimeDate,
                                                                            
                                                                            f_last_time AS fLastTime,
                                                                            `f_last_timestamp` AS fLastTimestamp,
                                                                            FROM_UNIXTIME( `f_last_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fLastTimeDate,
                                                                            
                                                                            `f_out_time` AS `fOutTime`,
                                                                            `f_out_timestamp` AS `fOutTimestamp`,
                                                                            FROM_UNIXTIME( `f_out_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS `fOutTimesDate`,

                                                                            f_mail_no AS fMailNo,
                                                                            f_num AS fNum,
                                                                            f_out_source AS fOutSource,
                                                                            f_out_way AS fOutWay,
                                                                            f_parcel_id AS fParcelId,
                                                                            f_parcel_status AS fParcelStatus,
                                                                            f_recipient_mobile AS fRecipientMobile,
                                                                            f_recipient_name AS fRecipientName,
                                                                            f_sms_notice_status AS fSmsNoticeStatus,
                                                                            f_station_id AS fStationId,
                                                                            f_take_code AS fTakeCode,
                                                                            f_type AS fType,
                                                                            f_weixin_notice_status AS fWeixinNoticeStatus,
                                                                            f_branch_id AS fBranchId,
                                                                            f_frame_code AS fFrameCode,
                                                                            f_comment AS fComment
                                                                        ', $ConditionSQL )

            ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')

            //获取站点名, 连表字段需 f_user_id
            ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
//            ->join('LEFT JOIN '. ( new \Home\Server\ParcelNoticeResultServer() ) ->getConditionTable_Result( $startDate, $endDate, '`f_parcel_id`,`f_weixin_notice`, `f_sms_notice`', '1=1' ) ->buildSql() .' AS `temp_parcel_notice_result` ON `temp_parcel_info`.`fParcelId` = `temp_parcel_notice_result`.`f_parcel_id`')
            ->order( $this ->getConditionStatus_Order( $parcel_status ) )
            ->page( $page, $size )
//            ->buildSql()
            ->select()
            ;

        //队列分表查询慢  改用in查询包裹信息
        foreach ( $Data as $v ){
            $parcelId[] = $v['fParcelId'];
        }

        $parcelId = implode( ',' , $parcelId );

        $Notice = new \Home\Server\ParcelNoticeResultServer();

        $parcelId = empty($parcelId) ? 0 : $parcelId;

        $where = "`f_parcel_id` in ({$parcelId})";

        $parcelNotice = $Notice->getConditionTable_Result( $startDate, $endDate, '`f_parcel_id`,f_weixin_notice AS fWeixinStatus, f_sms_notice AS fSmsStatus', $where )->select();

        //循环写入包裹发送状态
        foreach ( $Data as $k2=>$v2 ){
            $Data[$k2]['fWeixinStatus'] = '0';
            $Data[$k2]['fSmsStatus'] = '0';
            foreach ( $parcelNotice as $value ){
                if ( $v2['fParcelId'] == $value['f_parcel_id'] ){
                    $Data[$k2]['fWeixinStatus'] = $value['fWeixinStatus'];
                    $Data[$k2]['fSmsStatus'] = $value['fSmsStatus'];
                }
            }
        }

//        echo $Data;exit;
        return $Data;
    }


    /**
     * Function getConditionStorage
     * @param $station_id               站点ID
     * @param string $mobile            收件人手机号码
     * @param $date                     查询月份 (废弃)
     * @param int $parcel_status        包裹状态
     * @param int $page                 当前第几页
     * @param int $size                 每页多少条
     *     * @param int $expcomID             快递公司ID
     * @param string $mailNO            运单号
     * @param string $recipient_name    收件人
     * @param int $startDate            查询起始日期
     * @param int $endDate              查询结束日期
     * @param int $takeCode             提货码
     * @return mixed
     *
     * @return mixed
     *
     * Author:
     * Date: 2017-07-14
     * Info: 滞留件多状态查询
     */
    public function getRetentionStorage( $station_id, $mobile = '', $date = '', $parcel_status = 0, $page = 0, $size = 10
        , $expcomID = 0, $mailNO = '', $recipient_name = '', $startDate = 0, $endDate = 0, $takeCode = 0 ,$noticeWay = 0
    )
    {

        // 根据noticeWay进行筛选
        $ConditionSQL = $this ->getConditionSQL( $station_id, $mobile, $date, $parcel_status
            , $expcomID, $mailNO, $recipient_name, $takeCode
        );

        //API版 date数据有用。 未传  $startDate $endDate。 数据转换
        if( $startDate == 0 || $endDate == 0 )
        {
            //开始日期
            $startDate = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-01';

            //结束日期
            $endDate = date('Y-m-d', strtotime( '+1 month', strtotime( $startDate . ' 00:00:00' ) ) - 1 );
        }

        $field = '
                                                                            f_app_notice_status AS fAppNoticeStatus,
                                                                            f_company_id AS fCompanyId,
                                                                            f_company_name AS fCompanyName,
                                                                            f_input_source AS fInputSource,
                                                                            f_input_way AS fInputWay,
                                                                            f_is_detention AS fIsDetention,
                                                                            
                                                                            f_arrive_time AS fArriveTime,
                                                                            f_arrive_timestamp AS fArriveTimestamp,
                                                                            FROM_UNIXTIME( `f_arrive_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fArriveTimeDate,
                                                                            
                                                                            f_last_time AS fLastTime,
                                                                            `f_last_timestamp` AS fLastTimestamp,
                                                                            FROM_UNIXTIME( `f_last_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fLastTimeDate,
                                                                            
                                                                            `f_out_time` AS `fOutTime`,
                                                                            `f_out_timestamp` AS `fOutTimestamp`,
                                                                            FROM_UNIXTIME( `f_out_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS `fOutTimesDate`,

                                                                            f_mail_no AS fMailNo,
                                                                            f_num AS fNum,
                                                                            f_out_source AS fOutSource,
                                                                            f_out_way AS fOutWay,
                                                                            f_parcel_id AS fParcelId,
                                                                            f_parcel_status AS fParcelStatus,
                                                                            f_recipient_mobile AS fRecipientMobile,
                                                                            f_recipient_name AS fRecipientName,
                                                                            f_sms_notice_status AS fSmsNoticeStatus,
                                                                            f_station_id AS fStationId,
                                                                            f_take_code AS fTakeCode,
                                                                            f_type AS fType,
                                                                            f_weixin_notice_status AS fWeixinNoticeStatus,
                                                                            f_branch_id AS fBranchId,
                                                                            f_frame_code AS fFrameCode,
                                                                            f_comment AS fComment
                                                                        ';

        // 根据通知方式noticeWay，分别取数据，101 短信通知；102 电话通知； 103 送货上门
        if (in_array($noticeWay,array(101,102,103)) )
        {
            $Data = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->join('LEFT JOIN `tp_mobile_info` ON `temp_parcel_info`.`fStationId` = `tp_mobile_info`.`f_user_id` AND `temp_parcel_info`.`fRecipientMobile` = `tp_mobile_info`.`f_recipient_mobile`')
                ->join('LEFT JOIN `tp_receive_label` ON `tp_mobile_info`.`f_id` = `tp_receive_label`.`f_receive_id` AND `tp_mobile_info`.`f_user_id` = `tp_receive_label`.`f_station_id` ')
                ->where(['`tp_receive_label`.`f_receive_label_id` = '.$noticeWay])
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->page( $page, $size )
                ->select();
        }
        elseif ($noticeWay == 100)
        {
            $Data1 = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->select();

            $Data2 = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->join('LEFT JOIN `tp_mobile_info` ON `temp_parcel_info`.`fStationId` = `tp_mobile_info`.`f_user_id` AND `temp_parcel_info`.`fRecipientMobile` = `tp_mobile_info`.`f_recipient_mobile`')
                ->join('LEFT JOIN `tp_receive_label` ON `tp_mobile_info`.`f_id` = `tp_receive_label`.`f_receive_id` AND `tp_mobile_info`.`f_user_id` = `tp_receive_label`.`f_station_id` ')
                ->where(['`tp_receive_label`.`f_receive_label_id` IN (101,102,103)'])
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
//                ->buildSql()
                ->select()
            ;

            $Data2Arr = $DataAll = array();

            // 获取所有状态的包裹
            foreach ($Data2 as $k => $v)
            {
                $Data2Arr[] = $v['fMailNo'];
            }


            // 将状态为101,102,103状态的包裹剔除
            foreach ($Data1 as $key => $value)
            {
                if ( ! in_array( $value['fMailNo'] , $Data2Arr))
                {
                    $DataAll[] = $Data1[$key] ;
                }
            }

            // 分页
            $start = ( $page -1 ) * $size;
            $end = $page * $size - 1;

            // 获取分页后的包裹
            foreach ($DataAll as $akey => $aval)
            {
                if($akey >= $start && $akey <= $end)
                {
                    $Data[$akey] = $DataAll[$akey];
                }
            }

        }
        else
        {
            $Data = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->page( $page, $size )
//                ->buildSql();
                ->select();
        }

        //队列分表查询慢  改用in查询包裹信息
        foreach ( $Data as $v ){
            $parcelId[] = $v['fParcelId'];
        }

        $parcelId = implode( ',' , $parcelId );

        $Notice = new \Home\Server\ParcelNoticeResultServer();

        $parcelId = empty($parcelId) ? 0 : $parcelId;

        $where = "`f_parcel_id` in ({$parcelId})";

        $parcelNotice = $Notice->getConditionTable_Result( $startDate, $endDate, '`f_parcel_id`,f_weixin_notice AS fWeixinStatus, f_sms_notice AS fSmsStatus', $where )->select();

        //循环写入包裹发送状态
        foreach ( $Data as $k2=>$v2 ){
            $Data[$k2]['fWeixinStatus'] = '0';
            $Data[$k2]['fSmsStatus'] = '0';
            foreach ( $parcelNotice as $value ){
                if ( $v2['fParcelId'] == $value['f_parcel_id'] ){
                    $Data[$k2]['fWeixinStatus'] = $value['fWeixinStatus'];
                    $Data[$k2]['fSmsStatus'] = $value['fSmsStatus'];
                }
            }
        }

        return $Data;
    }


    /**
     * Function getConditionStorage
     * @param $station_id               站点ID
     * @param int $parcel_status        包裹状态
     * @param int $date                 查询月份
     * @param int $startDate            查询起始日期
     * @param int $endDate              查询结束日期
     * @param int $noticeWay            通知方式
     * Author:
     * Date: 2017-07-17
     * Info: 查询所有滞留件
     */
    public function getAllRetentionStorage( $station_id,  $parcel_status = 0 , $startDate = 0, $endDate = 0,$noticeWay = 0 ,$mobile = '' ,$mailNo = '')
    {

        // 根据noticeWay进行筛选
        $ConditionSQL = $this ->getConditionSQL( $station_id, $mobile, '', $parcel_status, '', $mailNo, '', '');



        $field = '
                                                                            f_app_notice_status AS fAppNoticeStatus,
                                                                            f_company_id AS fCompanyId,
                                                                            f_company_name AS fCompanyName,
                                                                            f_input_source AS fInputSource,
                                                                            f_input_way AS fInputWay,
                                                                            f_is_detention AS fIsDetention,
                                                                            
                                                                            f_arrive_time AS fArriveTime,
                                                                            f_arrive_timestamp AS fArriveTimestamp,
                                                                            FROM_UNIXTIME( `f_arrive_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fArriveTimeDate,
                                                                            
                                                                            f_last_time AS fLastTime,
                                                                            `f_last_timestamp` AS fLastTimestamp,
                                                                            FROM_UNIXTIME( `f_last_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fLastTimeDate,
                                                                            
                                                                            `f_out_time` AS `fOutTime`,
                                                                            `f_out_timestamp` AS `fOutTimestamp`,
                                                                            FROM_UNIXTIME( `f_out_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS `fOutTimesDate`,

                                                                            f_mail_no AS fMailNo,
                                                                            f_num AS fNum,
                                                                            f_out_source AS fOutSource,
                                                                            f_out_way AS fOutWay,
                                                                            f_parcel_id AS fParcelId,
                                                                            f_parcel_status AS fParcelStatus,
                                                                            f_recipient_mobile AS fRecipientMobile,
                                                                            f_recipient_name AS fRecipientName,
                                                                            f_sms_notice_status AS fSmsNoticeStatus,
                                                                            f_station_id AS fStationId,
                                                                            f_take_code AS fTakeCode,
                                                                            f_type AS fType,
                                                                            f_weixin_notice_status AS fWeixinNoticeStatus,
                                                                            f_branch_id AS fBranchId,
                                                                            f_frame_code AS fFrameCode,
                                                                            f_comment AS fComment
                                                                        ';

        // 根据通知方式noticeWay，分别取数据，101 短信通知；102 电话通知； 103 送货上门
        if (in_array($noticeWay,array(101,102,103)) )
        {
            $Data = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->join('LEFT JOIN `tp_mobile_info` ON `temp_parcel_info`.`fStationId` = `tp_mobile_info`.`f_user_id` AND `temp_parcel_info`.`fRecipientMobile` = `tp_mobile_info`.`f_recipient_mobile`')
                ->join('LEFT JOIN `tp_receive_label` ON `tp_mobile_info`.`f_id` = `tp_receive_label`.`f_receive_id` AND `tp_mobile_info`.`f_user_id` = `tp_receive_label`.`f_station_id` ')
                ->where(['`tp_receive_label`.`f_receive_label_id` = '.$noticeWay])
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->select();
        }
        elseif ($noticeWay == 100)
        {
            $Data1 = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->select();

            $Data2 = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->join('LEFT JOIN `tp_mobile_info` ON `temp_parcel_info`.`fStationId` = `tp_mobile_info`.`f_user_id` AND `temp_parcel_info`.`fRecipientMobile` = `tp_mobile_info`.`f_recipient_mobile`')
                ->join('LEFT JOIN `tp_receive_label` ON `tp_mobile_info`.`f_id` = `tp_receive_label`.`f_receive_id` AND `tp_mobile_info`.`f_user_id` = `tp_receive_label`.`f_station_id` ')
                ->where(['`tp_receive_label`.`f_receive_label_id` IN (101,102,103)'])
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
//                ->buildSql()
                ->select()
            ;

            $Data2Arr = $DataAll = array();

            // 获取所有状态的包裹
            foreach ($Data2 as $k => $v)
            {
                $Data2Arr[] = $v['fMailNo'];
            }


            // 将状态为101,102,103状态的包裹剔除
            foreach ($Data1 as $key => $value)
            {
                if ( ! in_array( $value['fMailNo'] , $Data2Arr))
                {
                    $Data[] = $Data1[$key] ;
                }
            }

        }
        else
        {
            $Data = $this ->getConditionTable_Result( $startDate, $endDate, $field, $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->select();
        }

        //队列分表查询慢  改用in查询包裹信息
        foreach ( $Data as $v ){
            $parcelId[] = $v['fParcelId'];
        }

        $parcelId = implode( ',' , $parcelId );

        $Notice = new \Home\Server\ParcelNoticeResultServer();

        $parcelId = empty($parcelId) ? 0 : $parcelId;

        $where = "`f_parcel_id` in ({$parcelId})";

        // 扩大选择时间，兼容“重新发送”功能
        $endtime = date('Y-m-d');

        $parcelNotice = $Notice->getConditionTable_Result( $startDate, $endtime, '*', $where )->select();


        return $parcelNotice;
    }


    /**
     * Function countConditionStorage
     * @param $station_id
     * @param string $mobile
     * @param $date
     * @param int $parcel_status
     * @return mixed
     *
     * Author:
     * Date: 2017-07-14
     * Info: 滞留件 统计
     */
    public function countRetentionStorage( $station_id, $mobile = '', $date, $parcel_status = 0
        , $expcomID = 0, $mailNO = '', $recipient_name = '', $startDate = 0, $endDate = 0, $takeCode = 0 ,$noticeWay
    )
    {
        //通用条件
        $ConditionSQL = $this ->getConditionSQL( $station_id, $mobile, $date, $parcel_status
            , $expcomID, $mailNO, $recipient_name, $takeCode
        );

        //API版 date数据有用。 未传  $startDate $endDate。 数据转换
        if( $startDate == 0 || $endDate == 0 )
        {
            //开始日期
            $startDate = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-01';

            //结束日期
            $endDate = date('Y-m-d', strtotime( '+1 month', strtotime( $startDate . ' 00:00:00' ) ) - 1 );
        }

        $field = '
                                                                            f_parcel_id AS fParcelId,
                                                                            f_mail_no AS fMailNo,
                                                                            f_recipient_mobile AS fRecipientMobile,
                                                                            f_recipient_name AS fRecipientName,
                                                                            f_station_id AS fStationId,
                                                                            f_arrive_time AS fArriveTime,
                                                                            f_arrive_timestamp AS fArriveTimestamp
                                                                        ';

        // 如果是101 短信通知；102 电话通知； 103 送货上门
        if ( in_array($noticeWay ,array(101,102,103)))
        {

            $list = $this ->getConditionTable_Result( $startDate, $endDate,  $field , $ConditionSQL )
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->join('LEFT JOIN `tp_mobile_info` ON `temp_parcel_info`.`fStationId` = `tp_mobile_info`.`f_user_id` AND `temp_parcel_info`.`fRecipientMobile` = `tp_mobile_info`.`f_recipient_mobile`')
                ->join('LEFT JOIN `tp_receive_label` ON `tp_mobile_info`.`f_id` = `tp_receive_label`.`f_receive_id` AND `tp_mobile_info`.`f_user_id` = `tp_receive_label`.`f_station_id` ')
                ->where(['`tp_receive_label`.`f_receive_label_id` = '.$noticeWay])
//                ->buildSql();
                ->select();

            $count = count($list);

            return $count;
        }
        elseif ($noticeWay == 100)
        {
            $Data1 = $this->getConditionTable_Result($startDate, $endDate, $field, $ConditionSQL)
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->order($this->getConditionStatus_Order($parcel_status))
                ->select();

            $Data2 = $this->getConditionTable_Result($startDate, $endDate, $field, $ConditionSQL)
                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                //获取站点名, 连表字段需 f_user_id
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->join('LEFT JOIN `tp_mobile_info` ON `temp_parcel_info`.`fStationId` = `tp_mobile_info`.`f_user_id` AND `temp_parcel_info`.`fRecipientMobile` = `tp_mobile_info`.`f_recipient_mobile`')
                ->join('LEFT JOIN `tp_receive_label` ON `tp_mobile_info`.`f_id` = `tp_receive_label`.`f_receive_id` AND `tp_mobile_info`.`f_user_id` = `tp_receive_label`.`f_station_id` ')
                ->where(['`tp_receive_label`.`f_receive_label_id` IN (101,102,103)'])
                ->order($this->getConditionStatus_Order($parcel_status))
//                ->buildSql()
                ->select();

            $Data2Arr = $DataAll = array();

            // 获取所有状态的包裹
            foreach ($Data2 as $k => $v) {
                $Data2Arr[] = $v['fMailNo'];
            }


            // 将状态为101,102,103状态的包裹剔除
            foreach ($Data1 as $key => $value) {
                if ( !in_array($value['fMailNo'], $Data2Arr)) {
                    $DataAll[] = $Data1[$key];
                }
            }

            $count = count($DataAll);

            return $count;
        }
        else
        {
            return $this ->getConditionTable_Result( $startDate, $endDate, 'f_parcel_id', $ConditionSQL )
                ->count("f_parcel_id");
        }


    }

    /**
     * Function countConditionStorage
     * @param $station_id
     * @param string $mobile
     * @param $date
     * @param int $parcel_status
     * @return mixed
     *
     * Author: 黄盖
     * Date: 2017-1-19 17:43
     * Info: 多状态查询 统计
     */
    public function countConditionStorage( $station_id, $mobile = '', $date, $parcel_status = 0
                                        , $expcomID = 0, $mailNO = '', $recipient_name = '', $startDate = 0, $endDate = 0, $takeCode = 0, $num = 0
                                    )
    {
        //通用条件
        $ConditionSQL = $this ->getConditionSQL( $station_id, $mobile, $date, $parcel_status
                                                , $expcomID, $mailNO, $recipient_name, $takeCode, $num
                                            );

        //API版 date数据有用。 未传  $startDate $endDate。 数据转换
        if( $startDate == 0 || $endDate == 0 )
        {
            //开始日期
            $startDate = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-01';

            //结束日期
            $endDate = date('Y-m-d', strtotime( '+1 month', strtotime( $startDate . ' 00:00:00' ) ) - 1 );
        }

        return $this ->getConditionTable_Result( $startDate, $endDate, 'f_parcel_id', $ConditionSQL )
                            ->count("f_parcel_id")
                            ;
    }

    /**
     * Function getConditionSQL
     * @param $station_id
     * @param string $mobile
     * @param $date
     * @param int $parcel_status    0 按照入库时间倒序  1按照提货时间倒序  其他 按照更新时间倒序
     *                  -1  查询所有条件
     *                  -250 查询已到站中的全部 ( 0 2 5 )
     * @return array
     *
     *
     *
     * Author: 黄盖
     * Date: 2017-1-19 17:43
     * Info: 多创建查询的SQL公用方法
     */
    public function getConditionSQL( $station_id, $mobile = '', $date, $parcel_status = 0
                                    , $expcomID = 0, $mailNO = '', $recipient_name = '', $takeCode = 0,$num = 0
                                )
    {
        $selectSQL = "`f_station_id` IN ( {$station_id} )";

        if( $expcomID > 0 )
        {
            $selectSQL .= " AND `f_company_id` = '{$expcomID}'";
        }

        if( $mobile != '' )
        {
            $selectSQL .= " AND `f_recipient_mobile` = '{$mobile}'";
        }

        if( $mailNO != '' )
        {
            $selectSQL .= " AND `f_mail_no` = '{$mailNO}'";
        }

        if( $num != '' )
        {
            $selectSQL .= " AND `f_num` = '{$num}'";
        }

        if( $recipient_name != '' )
        {
            $selectSQL .= " AND `f_recipient_name` = '{$recipient_name}'";
        }

        if( $takeCode > 0 )
        {
            $selectSQL .= " AND `f_take_code` = '{$takeCode}'";
        }

        //查包裹状态  已到站 中 的全部
        if( $parcel_status == -250 )
        {
            $selectSQL .= " AND `f_parcel_status` IN ( 0, 2, 5 )";
        }
        //包裹状态为4查询拒收的所有包裹 ，包含拒收出库
        else if( $parcel_status == 4 )
        {
            $selectSQL .= " AND `f_parcel_status` IN ( 4, 6 )";
        }
        //查包裹状态  -1 为全部数据,  非-1 则查指定状态
        else if( $parcel_status != -1 )
        {
            $selectSQL .= " AND `f_parcel_status` = '{$parcel_status}'";
        }
        else
        {

        }

        return $selectSQL;
    }

    /**
     * Function getConditionStatus_Order
     * @param int $parcel_status
     *
     * Author: 黄盖
     * Date: 2017-2-8 10:53
     * Info: 查询条件 根据 $parcel_status 查排序方式
     *                      0 按照入库时间倒序  1按照提货时间倒序  其他 按照更新时间倒序
     */
    public function getConditionStatus_Order( $parcel_status = 0 )
    {
        if( $parcel_status == 0 || $parcel_status == 2 || $parcel_status == 5 || $parcel_status == -250)
        {
            return '`fArriveTimestamp` DESC';
        }
        else if( $parcel_status == 1 )
        {
            return '`fOutTimestamp` DESC';
        }
        else
        {
            return '`fLastTimestamp` DESC';
        }
    }

    /**
     * Function getConditionTable_Result
     * @param $startDate
     * @param $endDate
     * @param $fields
     * @param $where
     * @return \Think\Model
     *
     * Author: 黄盖
     * Date: 2017-2-7 16:43
     * Info: 获取查询连表数据
     */
    public function getConditionTable_Result( $startDate, $endDate, $fields,  $where )
    {
        $tableName_Array = $NO_ExistsDate = Array();

        //查询哪些表
        if( ! empty( $startDate ) && ! empty( $endDate ) )
        {
            //2017-01-30   2017-03-01
            $startDateInfo = explode('-', $startDate);
            $endDateInfo   = explode('-', $endDate);

            //获取区间日期有哪些年月
            $MonthData = $this ->getYearMonth( $startDateInfo[0], $startDateInfo[1], $endDateInfo[0], $endDateInfo[1] );

            //获取存在哪些表
            $TableExists = ( new \Think\Model() ) ->query( "SHOW TABLES LIKE 'tp_parcel_info_%';" );
            $ExistsName = Array();

            //提取分表名
            foreach( $TableExists as $TKey => $TVal )
            {
                sort($TVal);
                $ExistsName[] = $TVal[0];
            }

            foreach( $MonthData as $MKey => $MVal )
            {
                if( in_array( 'tp_parcel_info_' . $MVal, $ExistsName ) )
                {
                    $tableName_Array[] = 'tp_parcel_info_' . $MVal;
                }
                else
                {
                    $NO_ExistsDate[] = $MVal;
                }
            }
        }
        //默认两个月
        else
        {
            $tableName_Array[] = $this ->Month_TableName_Now;
            $tableName_Array[] = $this ->LastTableName;
        }

        $UNION_Tables = '(';

        //交联主表
        if( ! empty( $NO_ExistsDate ) )
        {
            $UNION_Tables .= "
                            (
                                SELECT 
                                    {$fields}, 'tp_parcel_info' AS `table_name`
                                FROM
                                    `tp_parcel_info`
                                WHERE
                                    {$where} AND `f_arrive_timestamp` BETWEEN '". strtotime( $startDate . ' 00:00:00' ) ."' AND '". ( count( $tableName_Array ) > 0 ? strtotime('+1 month', strtotime( substr( $NO_ExistsDate[count( $NO_ExistsDate ) - 1], 0, 4 ) . '-' . substr( $NO_ExistsDate[count( $NO_ExistsDate ) - 1], 4, 2 ) . '-01 00:00:00' )) : strtotime( $endDate . ' 23:59:59' ) ) ."'
                            )
                        ";

            $UNION_Tables .= 'UNION';
        }

        //交联分表
        foreach( $tableName_Array as $TKey => $TVal )
        {
            $TimeWhere = '';

            //查询结束时间节点
            if( count( $tableName_Array ) - 1 == $TKey )
            {
                $TimeWhere .= ' AND `f_arrive_timestamp` <= ' . strtotime( $endDate . ' 23:59:59' );
            }

            //查询开始时间节点
            if( empty( $NO_ExistsDate ) && $TKey == 0 )
            {
                $TimeWhere .= ' AND `f_arrive_timestamp` >= ' . strtotime( $startDate . ' 00:00:00' );
            }


            $UNION_Tables .= "
                            (
                                SELECT 
                                    {$fields}, '{$TVal}' AS `table_name`
                                FROM
                                    `{$TVal}`
                                WHERE
                                    {$where} {$TimeWhere}
                            )
                        ";

            $UNION_Tables .= 'UNION';
        }

        $UNION_Tables = substr( $UNION_Tables, 0, -5 );

        $UNION_Tables .= ') AS `temp_parcel_info`';

        //返回连表资源
        return ( new \Think\Model() )
                ->field('*')
                ->table( $UNION_Tables );
    }

    /**
     * Function getYearMonth
     * @param $startYear
     * @param $startMonth
     * @param $endYear
     * @param $endMonth
     * @return array
     *
     * Author: 黄盖
     * Date: 2017-2-7 16:43
     * Info: 根据日期区间, 获取中间的年月
     */
    public function getYearMonth( $startYear, $startMonth, $endYear, $endMonth )
    {
        $MonthData = Array();
        $startMonth = intval( $startMonth );
        $endMonth = intval( $endMonth );

        for( $i = 0; $i <= $endYear - $startYear; $i++ )
        {
            $Now_Year = $startYear + $i;

            if( $Now_Year == $startYear && $Now_Year == $endYear )
            {
                for( $s = $startMonth; $s <= $endMonth; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }
            else if( $Now_Year == $startYear )
            {
                for( $s = $startMonth; $s <= 12; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }
            else if( $Now_Year == $endYear )
            {
                for( $s = 1; $s <= $endMonth; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }
            else
            {
                for( $s = 1; $s <= 12; $s ++ )
                {
                    $MonthData[] = $Now_Year . ( $s < 10 ? '0' . $s : $s );
                }
            }

        }

        sort( $MonthData );

        return $MonthData;
    }

    /**
     * Function countExpressStorage
     * @param $ExpID
     * @param string $mobile
     * @param $date
     * @param int $parcel_status
     * @return bool
     *
     * Author: 黄盖
     * Date: 2017-1-20 16:06
     * Info: 获取快递员 合作站点下面 的 包裹信息
     */
    public function countExpressStorage( $ExpID, $mobile = '', $date, $parcel_status = 0, $mailNO = '', $startDate = '', $endDate = '', $stationID = 0 )
    {
        //获取快递员的 公司ID 和 合作站点ID
        $ExpressInfo = $this ->getExpressInfo( $ExpID );

        $stationID = intval( $stationID );
        //直接查站点
        if( $stationID > 0 )
        {
            $ExpressInfo['stationID'] = $stationID;
        }

        if( $ExpressInfo )
        {

            //如果没有传月份  并且 没有传 日期，  初始化
            if( empty( $date ) && ( empty( $startDate ) || empty( $endDate ) ) )
            {
                $startDate = date('Y-m') . '-01';
                $endDate = date('Y-m-d');
            }
            //如果传了月份, 处理成日期
            else if( ! empty( $date ) )
            {
                //开始日期
                $startDate = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-01';

                //结束日期
                $endDate = date('Y-m-d', strtotime( '+1 month', strtotime( $startDate . ' 00:00:00' ) ) - 1 );
            }

            //通用条件
            $ConditionSQL = $this ->getConditionSQL( $ExpressInfo['stationID'], $mobile, $date, $parcel_status, $ExpressInfo['comID'], $mailNO );

            return $this ->getConditionTable_Result( $startDate, $endDate, 'f_parcel_id', $ConditionSQL )
                ->count("f_parcel_id")
                ;
        }
        else
        {
            return False;
        }
    }

    /**
     * Function getExpressStorage
     * @param $ExpID
     * @param string $mobile
     * @param $date
     * @param int $parcel_status
     * @param int $page
     * @param int $size
     * @return bool|mixed
     *
     * Author: 黄盖
     * Date: 2017-1-20 16:05
     * Info: 获取快递员 合作站点下面 的 包裹信息
     */
    public function getExpressStorage( $ExpID, $mobile = '', $date, $parcel_status = 0, $page = 1, $size = 10, $mailNO = '', $startDate = '', $endDate = '', $stationID = 0 )
    {
        //获取快递员的 公司ID 和 合作站点ID
        $ExpressInfo = $this ->getExpressInfo( $ExpID );

        $stationID = intval( $stationID );
        //直接查站点
        if( $stationID > 0 )
        {
            $ExpressInfo['stationID'] = $stationID;
        }

        if( $ExpressInfo )
        {

            //如果没有传月份  并且 没有传 日期，  初始化
            if( empty( $date ) && ( empty( $startDate ) || empty( $endDate ) ) )
            {
                $startDate = date('Y-m') . '-01';
                $endDate = date('Y-m-d');
            }
            //如果传了月份, 处理成日期
            else if( ! empty( $date ) )
            {
                //开始日期
                $startDate = substr( $date, 0, 4 ) . '-' . substr( $date, 4, 2 ) . '-01';

                //结束日期
                $endDate = date('Y-m-d', strtotime( '+1 month', strtotime( $startDate . ' 00:00:00' ) ) - 1 );
            }

            //通用条件
            $ConditionSQL = $this ->getConditionSQL( $ExpressInfo['stationID'], $mobile, $date, $parcel_status, $ExpressInfo['comID'], $mailNO );

            return $this ->getConditionTable_Result( $startDate, $endDate, '
                                                                            f_parcel_id AS fParcelId,
                                                                            f_parcel_status AS fParcelStatus,
                                                                            f_recipient_mobile AS fRecipientMobile,
                                                                            f_num AS fNum,
                                                                            f_mail_no AS fMailNo,
                                                                            f_recipient_name AS fRecipientName,
                                                                            f_app_notice_status AS fAppNoticeStatus,
                                                                            f_branch_id AS fBranchId,
                                                                            f_company_id AS fCompanyId,
                                                                            f_company_name AS fCompanyName,
                                                                            f_frame_code AS fFrameCode,
                                                                            f_input_source AS fInputSource,
                                                                            f_input_way AS fInputWay,
                                                                            f_is_detention AS fIsDetention,
                                                                            f_out_source AS fOutSource,
                                                                            f_out_way AS fOutWay,
                                                                            f_sms_notice_status AS fSmsNoticeStatus,
                                                                            f_station_id AS fStationId,
                                                                            f_take_code AS fTakeCode,
                                                                            f_type AS fType,
                                                                            f_weixin_notice_status AS fWeixinNoticeStatus,
                                                                            
                                                                            f_arrive_time AS fArriveTime,
                                                                            f_arrive_timestamp AS fArriveTimestamp,
                                                                            FROM_UNIXTIME( `f_arrive_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fArriveTimeDate,
                                                                            
                                                                            f_last_time AS fLastTime,
                                                                            `f_last_timestamp` AS fLastTimestamp,
                                                                            FROM_UNIXTIME( `f_last_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fLastTimeDate,
                                                                            
                                                                            `f_out_time` AS `fOutTime`,
                                                                            `f_out_timestamp` AS `fOutTimestamp`,
                                                                            FROM_UNIXTIME( `f_out_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS `fOutTimesDate`

                                                                        ', $ConditionSQL )

                ->field('
                        `temp_parcel_info`.*,
                        `tp_user`.`f_station_name` AS `stationName`
                    ')
                ->join('LEFT JOIN `tp_user` ON `temp_parcel_info`.`fStationId` = `tp_user`.`f_user_id`')
                ->order( $this ->getConditionStatus_Order( $parcel_status ) )
                ->page( $page, $size )
//                ->buildSql()
                ->select()
                ;
        }
        else
        {
            return False;
        }
    }

    /**
     * Function getExpressInfo
     * @param $ExpID            快递员ID
     * @return array|bool
     *
     * Author: 黄盖
     * Date: 2017-1-20 15:50
     * Info: 获取快递员的 公司ID 和 合作站点ID
     */
    private function getExpressInfo( $ExpID )
    {
        $expressData = ( new \Think\Model() )
                        ->table('tp_express_branch_com_dz')
                        ->field('`f_exp_id`, `f_com_id`, `f_station_id`, `f_branch_state`')
                        ->where("`f_exp_id` = '{$ExpID}' AND `f_branch_state` = 0")
//                        ->buildSql()
                      ->select()
                ;

        if( ! empty( $expressData ) )
        {
            //获取快递员的 公司ID 和 合作站点ID
            $expressCondition = Array( 'comID' => $expressData[0]['f_com_id'], 'stationID' => '' );

            foreach( $expressData as $key => $val )
            {
                $expressCondition['stationID'] .= $val['f_station_id'] . ',';
            }

            $expressCondition['stationID'] = substr( $expressCondition['stationID'], 0, -1 );

            return $expressCondition;
        }
        else
        {
            return False;
        }
    }

    /**
     * Function countMobileStorage
     * @param $mobile
     * @param int $parcel_status
     *
     * Author: 黄盖
     * Date: 2017-1-20 17:34
     * Info: 用户查询自己的包裹信息   最近两个月
     */
    public function countMobileStorage( $mobile, $parcel_status = 0 )
    {
        return $this ->getUnion_TableResource('
                                `f_parcel_id`
                        ',
            "`f_recipient_mobile` = '{$mobile}' AND `f_parcel_status` = '{$parcel_status}'"
        )
//            ->buildSql()
        ->count()
        ;
    }

    /**
     * Function getMobileStorage
     * @param $mobile
     * @param int $parcel_status
     * @param int $page
     * @param int $size
     * @return mixed
     *
     * Author: 黄盖
     * Date: 2017-1-20 17:52
     * Info: 用户查询自己的包裹信息   最近两个月
     */
    public function getMobileStorage( $mobile, $parcel_status = 0, $page = 1, $size = 10 )
    {
        return $this ->getUnion_TableResource('
                                `f_parcel_id` AS `parcelID`,
                                `f_station_id`,
                                f_mail_no AS fMailNo,
                                f_company_name AS fCompanyName,
                                f_take_code AS fTakeCode,
                                f_last_time AS fLastTime,
                                `f_last_timestamp` AS fLastTimestamp,
                                FROM_UNIXTIME( `f_last_timestamp`, \'%Y-%m-%d %H:%i:%S\') AS fLastTimeDate
                        ',
                        "`f_recipient_mobile` = '{$mobile}' AND `f_parcel_status` = '{$parcel_status}'"
                    )
            ->field('`temp_parcel_info`.*, `tp_user`.`f_user_mobile` AS `fUserMobile`, `tp_user`.`f_address` AS `fAddress`')
            ->join("`tp_user` ON `tp_user`.`f_user_id` = `temp_parcel_info`.`f_station_id`",'LEFT')
            ->page( $page, $size )
//            ->buildSql()
            ->select()
        ;
    }

    /**
     * Function getStorageField
     * @param string $String
     * @return string
     *
     * Author: 黄盖
     * Date: 2017-42-19 13:42
     * Info: 普通查询需要查哪个字段
     */
    private function getStorageField( $String = '' )
    {
        //手机号
        if( preg_match( "/^1[\d]{10}$/", $String ) )
        {
            return 'f_recipient_mobile';
        }
        //提货码
        else if( preg_match( "/^[\d]{6}$/", $String ) )
        {
            return 'f_take_code';
        }
        //运单号
        else
        {
            return 'f_mail_no';
        }

    }

    /**
     * Function getprofessional_StorageField
     * @param string $String
     * @return string
     *
     * Author: 黄盖
     * Date: 2017-4-6 18:59
     * Info: 专业版需要查哪个字段
     */
    private function getprofessional_StorageField( $String = '' )
    {
        //手机号
        if( preg_match( "/^1[\d]{10}$/", $String ) )
        {
            return 'f_recipient_mobile';
        }
        //运单号
        else if( preg_match( "/^[\w]{8,24}$/", $String ) )
        {
            return 'f_mail_no';
        }
        //编号
        else
        {
            return 'f_num';
        }

    }

    /**
     * Function update_StorageData
     * @param $update_StorageData
     * @return array
     *
     * Author: 黄盖
     * Date: 2017-24-18 16:24
     * Info: 修改数据
     */
    private function update_StorageData( $update_StorageData )
    {
        $UpdateResult = Array();

        foreach( $update_StorageData as $tableName => $Data )
        {
            foreach( $Data as $UKey => $UVal )
            {
                $UpdateResult[ $UKey ] = $UVal;
                $UpdateResult[ $UKey ]['f_parcel_id'] = $UKey;
                $UpdateResult[ $UKey ]['updateResult'] = intval( ( new \Think\Model() ) ->table( $tableName ) ->where("`f_parcel_id` = {$UKey}") ->data( $UVal ) ->save() );
            }
        }

        return $UpdateResult;
    }

    /**
     * Function insert_StorageData
     * @param $insert_StorageData
     * @return bool|string
     *
     * Author: 黄盖
     * Date: 2017-57-18 15:57
     * Info: 插入新数据
     */
    private function insert_StorageData( $insert_StorageData )
    {
        return ( new \Think\Model() ) ->table( $this ->Month_TableName_Now ) ->addAll( $insert_StorageData );
    }

    /**
     * Function MailNO_Repeat
     * @param array $MailNO_Data
     *
     * Author: 黄盖
     * Date: 2017-21-18 10:21
     * Info: 查询运单号是否重复
     */
    public function MailNO_Repeat( $Station_id, $MailNO_Data = Array() )
    {
        $MailNO_Data_Sql = '';

        foreach( $MailNO_Data as $Key => $Val )
        {
            $MailNO_Data_Sql .= "'{$Val}',";
        }

        $MailNO_Data_Sql = substr( $MailNO_Data_Sql, 0, -1 );

        $RepeatData = $this ->getUnion_TableResource(
                                    '`f_parcel_id`, `f_mail_no`, `f_recipient_mobile`',
                                    "`f_station_id` = '{$Station_id}' AND `f_mail_no` IN ( {$MailNO_Data_Sql} ) AND `f_parcel_status` IN ( 0,2,5 )"
                                )
//                                ->buildSql()
                                ->select()
        ;

        return $RepeatData;
    }


    /**
     * 判断站点下的包裹编号是否重复
     * @param $Station_id
     * @param $packetsArr_info
     * @return array
     */
    public function FrameCodeNum_Repeat( $Station_id ,$packetsArr_info )
    {
        // 获取站点当日所有包裹
        $date = date('Ymd',time());
        $beginTime = $date.'000000';
        $endTime = $date.'235959';

        //当月表中获取当日站点所有“编号”
        $result = $parcelModel =  ( new \Think\Model())
            -> table( $this -> Month_TableName_Now )
            -> where("`f_station_id` = {$Station_id} AND `f_arrive_time` BETWEEN {$beginTime} AND {$endTime}")
            -> field('f_frame_code,f_num')
            -> select();

        $packet = $returnArr['repeat'] = $returnArr['available'] = array();

        foreach ($result as $v)
        {
            $packet[] = $v['f_num'];
        }


        // 验证包裹是否重复
        foreach ($packetsArr_info as $value)
        {
            $str = $value['frameCode'].$value['num'];
            if (in_array($value['num'],$packet))
            {
                $value['code'] = $str;  // A7000001,ios使用
                $returnArr['repeat'][] = $value;
            }
            else
            {
                $returnArr['available'][] = $value;
            }
        }

        return $returnArr;
    }

    /**
     * Function Parcel_RealDelivery
     * @param array $DeliveryData
     *
     * Author: 黄盖
     * Date: 2017-2-5 14:40
     * Info: 向其他语言异步实时推送
     */
    public function Parcel_RealDelivery(  $insert_StorageData = Array(), $update_StorageData = Array() )
    {
        //取出站点ID + 快递公司ID
        $Putdata['UserId']      = 0;
        $Putdata['CompanyId']   = 0;
        $Putdata['PackageInfo'] = Array();

        //插入的数据组建
        foreach ( $insert_StorageData as $IKey => $IVal )
        {
            if( $Putdata['UserId'] == 0 || $Putdata['CompanyId'] == 0 )
            {
                $Putdata['UserId']     = intval( $IVal['f_station_id'] );
                $Putdata['CompanyId']  = intval( $IVal['f_company_id'] );
                $Putdata['Company']    = $IVal['f_company_name'];
				$Putdata['TableName']  = $IVal['table_name'];
            }

            $Putdata['PackageInfo'][] = Array(
                                            'MailNo'        => $IVal['f_mail_no'],
                                            'Mobile'        => $IVal['f_recipient_mobile'],
                                            'Num'           => $IVal['f_num'],
                                            'Frame'         => $IVal['f_frame_code'],
                                            'RecipientName' => $IVal['f_recipient_name'],
                                            'TakeCode'      => intval( $IVal['f_take_code'] ),
                                            'Parcelid'      => intval( $IVal['f_parcel_id'] )
											//,
                                            //'TableName'     => $IVal['table_name']
                            );
        }

        //更新的数据组建
        foreach ( $update_StorageData as $SKey => $SVal )
        {
            //更新的数据, 根据表名 分组 (3维数组)
            foreach( $SVal as $PKey => $PVal )
            {
                if( $Putdata['UserId'] == 0 || $Putdata['CompanyId'] == 0 )
                {
                    $Putdata['UserId']     = intval( $PVal['f_station_id'] );
                    $Putdata['CompanyId']  = intval( $PVal['f_company_id'] );
                    $Putdata['Company']    = $PVal['f_company_name'];
					$Putdata['TableName']  = SKey;
                }

                $Putdata['PackageInfo'][] = Array(
                                                'MailNo'        => $PVal['f_mail_no'],
                                                'Mobile'        => $PVal['f_recipient_mobile'],
                                                'Num'           => $PVal['f_num'],
                                                'Frame'         => $PVal['f_frame_code'],
                                                'RecipientName' => $PVal['f_recipient_name'],
                                                'TakeCode'      => intval( $PVal['f_take_code'] ),
                                                'Parcelid'      => intval( $PKey )
												//,
                                                //'TableName'     => $SKey
                                            );
            }
        }

        //统一字符类型
//        $Putdata = DataType_Uniform( $Putdata );

        //推送
        return $this ->useCURL_Post( 'http://192.168.1.122/Push/packagepush', json_encode( $Putdata ), 20, 'json' );
		
//        return file_put_contents( 't.txt', json_encode( $Putdata ) . "\r\n" . json_encode( $this ->useCURL_Post( 'http://192.168.1.122/Push/packagepush', json_encode( $Putdata ), 20, 'json' ) ) . "\n\r", FILE_APPEND );
    }

    /**
     * Function UserInfo_Redis
     * @param $stationID
     *
     * Author: 黄盖
     * Date: 2017-2-5 15:47
     * Info: 将用户信息(站点信息) 缓存
     */
    public function UserInfo_Redis( $stationID )
    {
        $stationID = intval( $stationID );
        $RedisKeyName = 'UserID_' . $stationID;

        if( $this ->redis )
        {
            //用户信息 用 0 数据库
            $this ->redis ->select( 0 );

            if( empty( $this ->redis ->HgetAll( $RedisKeyName ) ) )
            {
                //用户信息
                $UserInfo = ( new \Think\Model() ) ->table('tp_user')
                    ->field('
                            `tp_user`.`f_user_id`, 
                            `tp_user`.`f_address`, 
                            `tp_user`.`f_store_time`, 
                            `tp_user`.`f_user_mobile`, 
                            `tp_user`.`f_user_phone`, 
                            `tp_user`.`f_station_name`, 
                            `tp_sms_template`.`f_template_content`,
                            `tp_third_partner`.`f_partner_id`,
                            `tp_third_partner`.`f_partner_name`,
                            `tp_third_partner`.`f_partner_code`
                        ')
                    ->join('LEFT JOIN `tp_sms_template` ON `tp_user`.`f_template_id` > 0 AND `tp_user`.`f_template_id` = `tp_sms_template`.`f_template_id`')
                    ->join('LEFT JOIN `tp_third_partner` ON `tp_user`.`f_user_id` = `tp_third_partner`.`f_station_id`')
                    ->where("`f_user_id` = '{$stationID}' AND `f_user_status` = 1")
                    ->limit('1')
                    ->find()
                ;

                //默认模版内容
                $Defult_Template_Content = ( new \Think\Model() ) ->table('tp_sms_template')
                    ->field('`f_template_content`')
                    ->where("`f_template_status` = '1' AND `f_template_since` = '0' AND `f_isGol` = '1'")
                    ->find();


                //用户自定义模版  如果为空, 用默认模版
                if( empty( $UserInfo['f_template_content'] ) )
                {
                    $UserInfo['f_template_content'] = $Defult_Template_Content['f_template_content'];
                }


                //用户信息
//                $UserInfo = ( new \Think\Model() ) ->table('tp_user')
//                    ->field('`f_user_id`, `f_address`, `f_store_time`, `f_user_mobile`, `f_user_phone`, `f_station_name`')
//                    ->where(" `f_user_id` = '{$stationID}' AND `f_user_status` = 1")
//                    ->limit('1')
//                    ->find()
//                ;

                //站点注册快递信息
                $ExpressRegister = ( new \Think\Model() ) ->table('tp_station_register')
                    ->field('`f_id`, `f_station_id`, `f_com_id`, `f_orgCode`, `f_empCode`, `f_stationCode`, `f_appkey`, `f_password`')
                    ->where("`f_station_id` = '{$stationID}' AND `f_status` = 1")
                    ->select()
                ;

                //快递注册信息
                foreach( $ExpressRegister as $Ekey => $Eval )
                {
                    $UserInfo[ 'express_' . $Eval['f_com_id'] ] = $Eval['f_id'];

                    //韵达快递其他参数
                    if( $Eval['f_com_id'] == '109' )
                    {
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_orgCode' ]       = $Eval['f_orgCode'];
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_stationCode' ]   = $Eval['f_stationCode'];
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_appkey' ]        = $Eval['f_appkey'];
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_password' ]      = $Eval['f_password'];
                    }

                    //圆通快递其他参数
                    if( $Eval['f_com_id'] == '108' )
                    {
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_orgCode' ]       = $Eval['f_orgCode'];
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_empCode' ]       = $Eval['f_empCode'];
                        $UserInfo[ 'express_' . $Eval['f_com_id'] . '_stationCode' ]   = $Eval['f_stationCode'];
                    }
                }

                $this ->redis ->HMset( $RedisKeyName, $UserInfo );
            }
        }
    }

    /**
     * Function delRedis_UserInfo
     * @param $stationID
     *
     * Author: 黄盖
     * Date: 2017-2-20 9:19
     * Info: 用户信息修改之后
     */
    public function delRedis_UserInfo( $stationID )
    {
        $stationID = intval( $stationID );
        $RedisKeyName = 'UserID_' . $stationID;

        if( $this ->redis )
        {
            //用户信息 用 0 数据库
            $this->redis->select(0);

            $this->redis->del( $RedisKeyName );

            //重写用户信息
            $this ->UserInfo_Redis( $stationID );
        }
    }

    /**
     * Function INIT_userInfo_Redis
     *
     * Author: 黄盖
     * Date: 2017-2-5 17:59
     * Info: 初始化用户信息到REDIS
     */
    public function INIT_userInfo_Redis()
    {
        $ResetRedis = False;
        //重置数据
        if( isset( $_GET['reset'] ) && $_GET['reset'] == '84185858' )
        {
            $ResetRedis = True;
        }

        if( $this ->redis )
        {

            //用户信息 用 0 数据库
            $this ->redis ->select( 0 );

            /**
             * ****************************************** 用户信息 开始 ******************************************
             */
            //用户信息
            $UserInfo = ( new \Think\Model() ) ->table('tp_user')
                ->field('
                            `tp_user`.`f_user_id`, 
                            `tp_user`.`f_address`, 
                            `tp_user`.`f_store_time`, 
                            `tp_user`.`f_user_mobile`, 
                            `tp_user`.`f_user_phone`, 
                            `tp_user`.`f_station_name`, 
                            `tp_sms_template`.`f_template_content`
                        ')
                ->join('LEFT JOIN `tp_sms_template` ON `tp_user`.`f_template_id` > 0 AND `tp_user`.`f_template_id` = `tp_sms_template`.`f_template_id`')
                ->where('`f_user_status` = 1')
                ->select()
            ;

            //默认模版内容
            $Defult_Template_Content = ( new \Think\Model() ) ->table('tp_sms_template')
                ->field('`f_template_content`')
                ->where("`f_template_status` = '1' AND `f_template_since` = '0' AND `f_isGol` = '1'")
                ->find();

            //站点注册快递信息
            $ExpressRegister = ( new \Think\Model() ) ->table('tp_station_register')
                ->field('`f_id`, `f_station_id`, `f_com_id`, `f_orgCode`, `f_empCode`, `f_stationCode`, `f_appkey`, `f_password`')
                ->where('`f_status` = 1')
                ->select()
            ;

            //用户信息
            foreach( $UserInfo as $Ukey => $Uval )
            {
                //用户自定义模版  如果为空, 用默认模版
                if( empty( $Uval['f_template_content'] ) )
                {
                    $UserInfo[ $Ukey ]['f_template_content'] = $Defult_Template_Content['f_template_content'];
                }

                //快递注册信息
                foreach( $ExpressRegister as $Ekey => $Eval )
                {
                    if( $Uval['f_user_id'] == $Eval['f_station_id'] )
                    {
                        $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] ] = $Eval['f_id'];

                        //韵达快递其他参数
                        if( $Eval['f_com_id'] == '109' )
                        {
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_orgCode' ]       = $Eval['f_orgCode'];
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_stationCode' ]   = $Eval['f_stationCode'];
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_appkey' ]        = $Eval['f_appkey'];
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_password' ]      = $Eval['f_password'];
                        }


                        //圆通快递其他参数
                        if( $Eval['f_com_id'] == '108' )
                        {
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_orgCode' ]       = $Eval['f_orgCode'];
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_empCode' ]       = $Eval['f_empCode'];
                            $UserInfo[ $Ukey ][ 'express_' . $Eval['f_com_id'] . '_stationCode' ]   = $Eval['f_stationCode'];
                        }
                    }
                }
            }

            //用户(站点)信息、站点快递注册信息 写入redis
            foreach( $UserInfo as $key => $val )
            {
                $RedisKeyName = 'UserID_' . $val['f_user_id'];

                //删除原redis数据, 更新
                if( $ResetRedis )
                {
                    //删除
                    $this ->redis ->del( $RedisKeyName );

                    //写入
                    $this ->redis ->HMset( $RedisKeyName, $val );
                }
                //不重置, 则存在跳过, 不存在插入
                else if( empty( $this ->redis ->HgetAll( $RedisKeyName ) ) )
                {
                    $this ->redis ->HMset( $RedisKeyName, $val );
                }
            }

            echo 'INIT_userInfo_Redis<br/>';

            /**
             * ****************************************** 用户信息 结束 ******************************************
             */










            /**
             * ****************************************** 微信信息 开始 ******************************************
             */

            //微信信息 用 1 数据库
            $this ->redis ->select( 1 );

            //用户手机号码 绑定 wxopenid
            $OpenidData = ( new \Think\Model() )
                ->table('wechat.ims_pc_xiongmiao')
                ->field('`id`, `weid`, `phone`, `openid`')
                ->where('`unfollow` = 0')
//                                    ->buildSql()
                ->select()
            ;

            $MobileExisrs_Array = Array();

            //处理数据  Array( Mobile => Array( 微信ID => 其OPENID ) )
            foreach( $OpenidData as $OKey => $OVal )
            {
                $MobileExisrs_Array[ $OVal['phone'] ][ $OVal['weid'] ] = $OVal['openid'];
            }

            //取出数据进Redis
            foreach( $MobileExisrs_Array as $MKey => $MVal )
            {
                $RedisKeyName = 'WxOpenID_' . $MKey;

                //删除原redis数据, 更新
                if( $ResetRedis )
                {
                    //删除
                    $this ->redis ->del( $RedisKeyName );

                    //写入
                    $this ->redis ->HMset( $RedisKeyName, $MVal );
                }
                //不重置, 则存在跳过, 不存在插入
                else if( empty( $this ->redis ->HgetAll( $RedisKeyName ) ) )
                {
                    $this ->redis ->HMset( $RedisKeyName, $MVal );
                }
            }


            echo 'INIT_wxopenid_Redis<br/>';

            /**
             * ****************************************** 微信信息 开始 ******************************************
             */







            exit;
        }
        else
        {
            echo 'Redis FAIL';
            exit;
        }
    }

    /**
     * Function getMailNO
     * @param array $StorageData
     * @return array
     *
     * Author: 黄盖
     * Date: 2017-16-18 10:16
     * Info: 获取运单号数据
     */
    private function getMailNO( $StorageData = Array() )
    {
        $MailNO_Data = Array();

        foreach( $StorageData as $Key => $Val )
        {
            $MailNO_Data[] = $Val['f_mail_no'];
        }

        return $MailNO_Data;
    }

    /**
     * Function Allow_TakeCode
     * @param $Station_id
     * @param int $count
     * @return array
     *
     * Author: 黄盖
     * Date: 2017-22-18 15:22
     * Info: 获取能用的提货码
     */
    public function Allow_TakeCode( $Station_id, $count = 10 )
    {
        //获取提货码
        $TakeCodeData = $this ->getTakeCode( $count );

        //获取提货码是否重复
        $TakeCodeData_Repeat = $this ->TakeCode_Repeat( $Station_id, $TakeCodeData );

        //删除重复的提货码
        foreach( $TakeCodeData as $TKey => $TVal )
        {
            foreach( $TakeCodeData_Repeat as $RKey => $RVal )
            {
                if( $TVal == $RVal['f_take_code'] )
                {
                    unset( $TakeCodeData[ $TKey ] );
                }
            }
        }

        //重复的太多, 不够用, 递归获取更多
        if( count( $TakeCodeData ) < $count )
        {
            $TakeCodeData = array_merge( $TakeCodeData, $this ->Allow_TakeCode( $Station_id, $count ) );
        }

        $AllowData = Array();

        //就算生成的提货码数据库里没有，也要防止当前生成的有没有重复
        foreach( $TakeCodeData as $AKey => $AVal )
        {
            if( ! in_array( $AVal, $AllowData ) )
            {
                $AllowData[] = $AVal;
            }
        }

        return $AllowData;
    }

    /**
     * Function testAllow_TakeCode
     * @param int $Station_id
     * @param int $count
     * @return array
     *
     * Author: 黄盖
     * Date: 2017-1-20 15:01
     * Info: 测试用
     */
    public function testAllow_TakeCode( $Station_id = 293, $count = 50 )
    {
        //获取提货码
        $TakeCodeData = $this ->getTakeCode( $count );

        $TakeCode_Data_Sql = '';

        foreach( $TakeCodeData as $Key => $Val )
        {
            $TakeCode_Data_Sql .= "'{$Val}',";
        }

        $TakeCode_Data_Sql = substr( $TakeCode_Data_Sql, 0, -1 );


        $take_code =  ( new \Think\Model() )
                ->table('tp_parcel_info')
                ->field('`f_parcel_id`,`f_take_code`')
                ->where(" `f_station_id` = '293' AND `f_take_code` IN ( {$TakeCode_Data_Sql} ) ")
//                ->buildSql()
                ->select()
            ;

        foreach ( $TakeCodeData as $key => $val )
        {
            foreach( $take_code as $TKey => $TVal )
            {
                if( $TVal['f_take_code'] == $val )
                {
                    unset( $TakeCodeData[ $key ] );
                }
            }
        }

        sort( $TakeCodeData );

        return $TakeCodeData;
    }

    /**
     * Function TakeCode_Repeat
     * @param $Station_id
     * @param array $TakeCode_Data
     * @return mixed
     *
     * Author: 黄盖
     * Date: 2017-45-18 14:45
     * Info: 查询提货码是否重复
     */
    public function TakeCode_Repeat( $Station_id, $TakeCode_Data = Array() )
    {
        $TakeCode_Data_Sql = '';

        foreach( $TakeCode_Data as $Key => $Val )
        {
            $TakeCode_Data_Sql .= "'{$Val}',";
        }

        $TakeCode_Data_Sql = substr( $TakeCode_Data_Sql, 0, -1 );

         $RepeatData = $this ->getUnion_TableResource(
                                        '`f_parcel_id`, `f_take_code`',
                                        "`f_station_id` = '{$Station_id}' AND `f_parcel_status` IN ( 0, 2, 5 ) AND `f_take_code` IN ( {$TakeCode_Data_Sql} )"
                                )
//                                ->buildSql()
                                 ->select()
        ;

        return $RepeatData;
    }

    /**
     * Function getTakeCode
     * @param int $Count
     *
     * Author: 黄盖
     * Date: 2017-26-18 9:26
     * Info: 获取提货码
     */
    private function getTakeCode( $Count = 0 )
    {
        $Data = Array();

        //多取几个个，防止重复
        for( $i = 0; $i < ( $Count * 1.2 ) + 1; $i ++ )
        {
            $randData = rand( 100000, 999999 );

            if( ! in_array( $randData, $Data ) )
            {
                $Data[] = $randData;
            }
            else
            {
                $i = $i - 1;
            }
        }

        return $Data;
    }

    /**
     * Function getLatsFNum
     * @param $stationID
     * @return string
     *
     * Author: 黄盖
     * Date: 2017-2-7 14:28
     * Info: 获取站点最后一次的入库包裹 f_num
     */
    public function getLatsFNum( $stationID )
    {
        $Data = ( new \Think\Model() )  ->table( $this ->Month_TableName_Now )
                                ->field('`f_parcel_id`, `f_num`')
                                ->where("`f_station_id` = '{$stationID}'")
                                ->order('`f_parcel_id` DESC')
                                ->limit('1')
//                                ->buildsql()
                                ->find()
                                ;
        if( ! empty( $Data['f_num'] ) )
        {
            return $Data['f_num'];
        }
        else
        {
            return date('ymd') . '01';
        }
    }

    /**
     * Function Integrate
     * @param array $Data
     *
     * Author: 黄盖
     * Date: 2017-38-18 9:38
     * Info: 整合数据
     */
    private function Integrate( $Data = Array() )
    {
        if( isset( $Data[0] ) )
        {
            return $Data;
        }
        else
        {
            return Array( $Data );
        }
    }

    /**
     * Function getJoinTableData
     *
     * Author: 黄盖
     * Date: 2017-14-18 10:14
     * Info: 连表查询的对象
     */
    private function getJoinTableData()
    {
        return ( new \Think\Model() )
            ->table( "( SELECT *, '{$this ->Month_TableName_Now}' AS `table_name` FROM `{$this ->Month_TableName_Now}` UNION SELECT *, '{$this ->LastTableName}' AS `table_name` FROM `{$this ->LastTableName}` ) AS `new_parcel_info`" )
        ;
    }

    /**
     * Function getUNION_TableData
     * @param $fields       查询字段值 `field1`, `field2`, ....
     * @param $where        查询条件   `id` = 1 AND `val` = 2, ....
     * @return \Think\Model
     *
     * Author: 黄盖
     * Date: 2017-0-19 15:00
     * Info: 新建连表核心功能, 原连表貌似有误
     */
    public function getUnion_TableResource( $fields,  $where )
    {
        return ( new \Think\Model() )
                ->field('*')
                ->table(
                            "(
                                (
                                    SELECT 
                                        {$fields}, '{$this ->Month_TableName_Now}' AS `table_name`
                                    FROM
                                        `{$this ->Month_TableName_Now}`
                                    WHERE
                                        {$where}
                                )
                                UNION
                                    (
                                        SELECT
                                            {$fields}, '{$this ->LastTableName}' AS `table_name`
                                        FROM
                                            `{$this ->LastTableName}`
                                        WHERE
                                            {$where}
                                    )
                            ) AS `temp_parcel_info`
                            "
                        );
    }

    /**
     * Function LastTableName
     *
     * Author: 黄盖
     * Date: 2017-23-18 9:23
     * Info: 获取连上一个月的表名
     */
    private function LastTableName()
    {
        //查询表名
        $Exists = ( new \Think\Model() ) ->query( "SHOW TABLES LIKE '{$this ->Month_TableName_Last}';" );

        //表存在则连月份表
        if( $Exists )
        {
            $this ->LastTableName = $this ->Month_TableName_Last;
        }
        //表不存在, 则连主表
        else
        {
            $this ->LastTableName = 'tp_parcel_info';
        }
    }

    /**
     * Function Table_Exists
     * @return false|int
     *
     * Author: 黄盖
     * Date: 2017-59-17 17:59
     * Info: 查询分表是否存在
     */
    private function Table_Exists()
    {
        //查询表名
        $Exists = ( new \Think\Model() ) ->query( "SHOW TABLES LIKE '{$this ->Month_TableName_Now}';" );

        //表不存在则创建
        if( ! $Exists )
        {
            //查询上一个表的自增ID, 包裹主键ID不允许重复
            $Table_STATUS = ( new \Think\Model() ) ->query( "SHOW TABLE STATUS LIKE '{$this ->LastTableName}';" );

            return $this ->AutoCreate_Table( $Table_STATUS[0]['Auto_increment'] + 10000 );
        }

        return True;
    }

    /**
     * Function AutoCreate_Table
     * @return false|int
     *
     * Author: 黄盖
     * Date: 2017-59-17 17:59
     * Info: 创建自动创建分表
     */
    private function AutoCreate_Table( $Auto_increment )
    {
        $CreateSQL = "
            CREATE TABLE `{$this ->Month_TableName_Now}` (
              `f_parcel_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '包裹ID',
              `f_exp_id` int(11) DEFAULT '0' COMMENT '快递员ID',
              `f_branch_id` int(11) DEFAULT '0' COMMENT '网点ID',
              `f_station_id` int(11) NOT NULL DEFAULT '0' COMMENT '站点ID',
              `f_mail_no` varchar(100) DEFAULT '' COMMENT '运单号',
              `f_company_id` int(11) DEFAULT '0' COMMENT '快递公司ID',
              `f_company_name` varchar(20) DEFAULT '' COMMENT '快递公司名称',
              `f_recipient_name` varchar(20) DEFAULT '' COMMENT '收件人姓名',
              `f_recipient_mobile` varchar(20) DEFAULT '' COMMENT '收件人手机号码',
              `f_frame_code` varchar(10) DEFAULT '' COMMENT '货架code',
              `f_take_code` int(11) DEFAULT '0' COMMENT '提货码',
              `f_num` varchar(65) DEFAULT '0' COMMENT '编号',
              `f_input_way` tinyint(1) DEFAULT '9' COMMENT '录入方式 0.单件入库 1.批量入库  9未操作默认',
              `f_input_source` tinyint(1) DEFAULT '9' COMMENT '录入来源   0.PC 1.IOS 2.Andoird 3.微信  9未操作默认  -1.pc修改  -2.IOS修改  -3.Android修改',
              `f_arrive_time` bigint(14) DEFAULT '0' COMMENT '到站时间 日期',
              `f_arrive_timestamp` int(11) DEFAULT '0' COMMENT '到站时间 时间戳',
              `f_parcel_status` tinyint(1) DEFAULT '2' COMMENT '0.已到站 1.已提货 2.待完善 3.异常  4.拒收 5.通知失败 6.拒收出库 9未操作默认',
              `f_is_detention` tinyint(1) DEFAULT '9' COMMENT '是否是滞留件 0.正常 1.滞留  9未操作默认',
              `f_out_way` tinyint(1) DEFAULT '0' COMMENT ' 出库平台  0 未知（老版APP）  1 IOS  2 Andoird  3 PC  5 微信',
              `f_out_source` tinyint(1) DEFAULT '1' COMMENT '出库方式  1 提货码  6 超级密码  7 专业版  8 微信扫码',
              `f_app_notice_status` tinyint(1) DEFAULT '9' COMMENT 'APP通知状态   0.成功 1.失败 2.未开启  9未操作默认',
              `f_weixin_notice_status` tinyint(1) DEFAULT '9' COMMENT '微信通知状态  0.成功 1.失败 2.未开启  9未操作默认',
              `f_sms_notice_status` tinyint(1) DEFAULT '9' COMMENT '短信通知状态  0.成功 1.失败 2.未开启  9未操作默认',
              `f_out_time` bigint(14) DEFAULT '0' COMMENT '包裹提货时间  日期',
              `f_out_timestamp` int(11) DEFAULT '0' COMMENT '包裹提货时间  时间戳',
              `f_last_time` bigint(14) DEFAULT '0' COMMENT '包裹最后更新时间 日期',
              `f_last_timestamp` int(11) DEFAULT '0' COMMENT '包裹最后更新时间 时间戳',
              `f_type` tinyint(1) DEFAULT '9' COMMENT '包裹类型         0:免费件   1.收费件  9未操作默认',
              `f_comment` varchar(200) DEFAULT '' COMMENT '拒收理由',
              `source` enum('pc','android','pda','ios') DEFAULT 'pc' COMMENT '来源平台',
              `version` varchar(15) DEFAULT '0' COMMENT '版本号',
              PRIMARY KEY (`f_parcel_id`),
              KEY `f_mail_no` (`f_mail_no`),
              KEY `f_take_code` (`f_take_code`),
              KEY `f_recipient_mobile` (`f_recipient_mobile`),
              KEY `f_parcel_status` (`f_parcel_status`),
              KEY `f_station_id` (`f_station_id`)
            ) ENGINE=InnoDB AUTO_INCREMENT={$Auto_increment} DEFAULT CHARSET=utf8 COMMENT='包裹数据分表';
        ";

        //创建表
        return ( new \Think\Model() ) ->execute( $CreateSQL );
    }
}
?>